Skip to content

Module System

Harneet supports a comprehensive module system with Go.mod integration for external dependencies and version management.

Overview

The module system provides:

  • go.mod integration - Standard Go module files for dependency management
  • External module resolution - Automatic downloading and caching of dependencies
  • Version management - Semantic versioning support
  • Import path mapping - Clean import syntax for external modules
  • Module caching - Efficient local caching in imports/ directory

Project Structure

1
2
3
4
5
6
7
8
myproject/
├── go.mod              # Module definition and dependencies
├── main.ha             # Main application file
├── imports/            # Downloaded external modules (auto-generated)
│   ├── github.com/example/utils@v1.0.0/
│   └── github.com/example/math@v1.2.0/
└── local/              # Local packages
    └── mypackage/

go.mod File

Create a go.mod file in your project root:

1
2
3
4
5
6
7
8
module example.com/myproject

go 1.21

require (
    github.com/example/utils v1.0.0
    github.com/example/math v1.2.0
)

Import Syntax

External Modules

External Modules
1
2
3
4
5
6
7
import "github.com/example/utils" as utils
import "github.com/example/math" as math

function main() {
    var result = utils.FormatString("Hello, %s!", "World")
    var sum = math.Add(10, 20)
}

Local Packages

Local Packages
import "./local/mypackage" as pkg
import "../shared/common" as common

HMOD Tool

HMOD tool is not needed. We are stil working on bringing go packages to Harneet. Kindly stay tuned. As of today , you dont need HMOD tool

Module Management Tool

Use the hmod tool to manage dependencies:

Initialize a Project

hmod init --module example.com/myproject

Add Dependencies

hmod require --module github.com/example/utils --version v1.0.0

Download Dependencies

hmod download

List Dependencies

hmod list

Clean Cache

hmod clean

Module Resolution

The module system resolves imports in the following order:

  1. Standard Library - Built-in modules (fmt, json, os, etc.)
  2. External Modules - Modules listed in go.mod
  3. Local Packages - Relative path imports (./package, ../package)

External Module Resolution

For import github.com/example/utils/strings:

  1. Parse go.mod to find matching module github.com/example/utils v1.0.0
  2. Check if module exists in imports/github.com/example/utils@v1.0.0/
  3. If not found, download module automatically
  4. Resolve subpath: imports/github.com/example/utils@v1.0.0/strings/

Version Management

Semantic Versioning

Harneet follows semantic versioning (semver):

1
2
3
4
require (
    github.com/example/utils v1.0.0    // Exact version
    github.com/example/math v1.2.0     // Exact version
)

Version Constraints

Currently supported: - Exact versions: v1.0.0 - Pre-release: v1.0.0-alpha.1 - Build metadata: v1.0.0+build.1

Module Downloading

The module manager supports multiple download methods:

Go Module Cache

# Uses go mod download when available
go mod download github.com/example/utils@v1.0.0

Git Clone Fallback

# Falls back to git clone for repositories
git clone --depth 1 --branch v1.0.0 https://github.com/example/utils.git

Supported Hosting

  • GitHub: github.com/user/repo
  • GitLab: gitlab.com/user/repo
  • Bitbucket: bitbucket.org/user/repo
  • Custom: Any git-accessible repository

Module Caching

Downloaded modules are cached in the imports/ directory:

imports/
├── github.com/example/utils@v1.0.0/
│   ├── strings/
│   │   └── strings.ha
│   └── format/
│       └── format.ha
└── github.com/example/math@v1.2.0/
    ├── basic/
    │   └── math.ha
    └── advanced/
        └── calc.ha

Cache Management

  • Automatic: Modules downloaded on first import
  • Manual: Use harneet-mod download to pre-download
  • Cleanup: Use harneet-mod clean to remove cache

Package Structure

External modules should follow Harneet package conventions:

Package Declaration

Package Declaration
// strings/strings.ha
package strings

// Exported function (uppercase)
function FormatString(template string, args ...interface{}) string {
    // Implementation
}

// Private function (lowercase)
function helper(s string) string {
    // Implementation
}

Exports

Only uppercase identifiers are exported:

Export Rules
1
2
3
4
5
6
7
8
9
// Exported
var DefaultTimeout int = 30
function ProcessData() {}
type User struct {}

// Not exported
var internalConfig = {}
function parseInternal() {}
type privateType struct {}

Integration Examples

Configuration Management with Viper

Go Modules Config
1
2
3
4
5
6
7
// go.mod
module example.com/sample-project

require (
    github.com/spf13/viper v1.17.0
    github.com/fatih/color v1.15.0
)
Viper Configuration
// main.ha
package main

import fmt
import "github.com/spf13/viper" as viper
import "github.com/fatih/color" as color

function init() {
    viper.SetConfigName("config")
    viper.SetConfigType("toml")
    viper.AddConfigPath(".")
}

function main() {
    var green = color.New(color.FgGreen).SprintFunc()

    var err = viper.ReadInConfig()
    if err != nil {
        fmt.Printf("Error reading config: %v\n", err)
        return
    }

    var appName = viper.GetString("app.name")
    var port = viper.GetInt("app.port")

    fmt.Printf("%s App: %s running on port %d\n", green("✅"), appName, port)
}

CLI Tool

CLI Tool Modules
1
2
3
4
5
6
7
// go.mod
module example.com/cli-tool

require (
    github.com/urfave/cli/v2 v2.25.0
    github.com/fatih/color v1.15.0
)
CLI Tool Main
// main.ha
package main

import "github.com/urfave/cli/v2" as cli
import "github.com/fatih/color" as color

function main() {
    var app = cli.NewApp()
    app.Name = "mytool"

    color.Green("CLI tool ready!")
}

Best Practices

Module Organization

  1. Single Purpose: Each module should have a clear, single purpose
  2. Clear Exports: Export only necessary functions and types
  3. Documentation: Document exported functions and types
  4. Versioning: Use semantic versioning for releases

Import Management

  1. Group Imports: Group standard library, external, and local imports
  2. Meaningful Aliases: Use clear, descriptive import aliases
  3. Avoid Conflicts: Prevent naming conflicts with aliases
Import Best Practices
1
2
3
4
5
6
7
8
9
// Good import grouping
import fmt
import json

import "github.com/example/utils" as utils
import "github.com/example/math" as math

import "./local/database" as db
import "../shared/config" as config

Dependency Management

  1. Pin Versions: Use exact versions in production
  2. Regular Updates: Keep dependencies updated
  3. Security: Review dependencies for security issues
  4. Minimal Dependencies: Only add necessary dependencies

Error Handling

Module Not Found

ERROR: module or package 'github.com/example/missing' not found

Solution: Add module to go.mod and run harneet-mod download

Version Conflicts

ERROR: version conflict for github.com/example/utils

Solution: Update go.mod with compatible versions

Download Failures

ERROR: failed to download module github.com/example/utils: git clone failed

Solution: Check network connectivity and repository access

Advanced Features

Module Replacement

// go.mod
replace github.com/example/utils => ./local/utils

Indirect Dependencies

1
2
3
4
require (
    github.com/example/utils v1.0.0
    github.com/example/math v1.2.0 // indirect
)

Build Constraints

Build Constraints
1
2
3
4
5
// +build linux darwin

package platform

// Platform-specific code

Migration Guide

From Local Packages

  1. Create go.mod file
  2. Move packages to external repositories
  3. Update import paths
  4. Use harneet-mod to manage dependencies

From Other Languages

  1. Identify equivalent Harneet packages
  2. Create go.mod with dependencies
  3. Adapt import syntax
  4. Update function calls to match Harneet conventions

Troubleshooting

Common Issues

  1. Import cycles: Reorganize package dependencies
  2. Version conflicts: Update to compatible versions
  3. Missing modules: Add to go.mod and download
  4. Permission errors: Check file system permissions

Debug Mode

HARNEET_DEBUG=1 ./harneet main.ha

Verbose Logging

hmod download --verbose

This module system brings enterprise-level dependency management to Harneet while maintaining simplicity and Go-like familiarity.