fglpkg

module
v1.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2026 License: MIT

README

fglpkg — Genero BDL Package Manager

A package manager for Genero BDL projects, supporting both BDL packages and Java JAR dependencies.

Project Structure

fglpkg/
├── cmd/
│   ├── fglpkg/main.go              # Package manager CLI entry point
│   ├── registry/main.go            # Registry server entry point
│   └── build.sh                    # Cross-platform build script
├── internal/
│   ├── cli/cli.go                  # Command dispatch & user interaction
│   ├── manifest/manifest.go        # fglpkg.json parsing & manipulation
│   ├── semver/                     # Semver parsing & constraint matching
│   ├── genero/genero.go            # Genero BDL version detection
│   ├── resolver/resolver.go        # Transitive dependency resolution
│   ├── installer/installer.go      # Zip download, extraction, JAR management
│   ├── lockfile/lockfile.go        # fglpkg.lock read/write/validate
│   ├── checksum/checksum.go        # SHA256 streaming verification
│   ├── credentials/                # Registry + GitHub credential storage
│   ├── github/github.go            # GitHub Releases API client
│   ├── workspace/workspace.go      # Monorepo workspace support
│   ├── registry/registry.go        # Registry HTTP client
│   └── registry/server/            # Registry HTTP server
│       ├── server.go               # Route handlers
│       ├── store.go                # Flat-file storage backend
│       └── testing.go              # Test helper (NewTestServer)
├── docs/
│   ├── user-guide.md               # User instruction guide
│   └── github-token-setup.md       # GitHub PAT setup instructions
├── .github/workflows/release.yml   # Automated release on tag push
├── go.mod
└── README.md

Installation

Download the latest binary for your platform from GitHub Releases and place it in your PATH:

# macOS / Linux
sudo cp fglpkg-darwin-arm64 /usr/local/bin/fglpkg
sudo chmod +x /usr/local/bin/fglpkg
# Windows — copy to a directory in your PATH
copy fglpkg-windows-amd64.exe C:\tools\fglpkg.exe

Add environment setup:

macOS / Linux — add to ~/.bashrc or ~/.zshrc:

echo 'eval "$(fglpkg env --global)"' >> ~/.bashrc
source ~/.bashrc

Windows (cmd.exe) — create a setup-env.bat script or run before building:

FOR /F "tokens=*" %%i IN ('fglpkg env --global') DO %%i

Genero Studio — paste the output of fglpkg env --gst into your project's environment settings.

Use --global in shell profiles so all installed packages are available regardless of your current directory.

Building from Source

go build -o fglpkg ./cmd/fglpkg

Use the build script to cross-compile for all platforms with embedded version info:

./cmd/build.sh                    # uses default version from script
FGLPKG_VERSION=2.0.0 ./cmd/build.sh   # override version

This produces ARM and Intel binaries for Linux, macOS, and Windows in the ./bin/ directory.

Home Directory Layout

fglpkg stores everything under ~/.fglpkg (override with FGLPKG_HOME):

~/.fglpkg/
├── packages/          # Installed BDL packages (each in its own subdir)
│   ├── myutils/
│   │   ├── fglpkg.json
│   │   ├── strings.42m
│   │   └── dates.42m
│   └── poiapi/
│       └── com/fourjs/poiapi/
│           ├── fglpkg.json
│           └── PoiApi.42m
├── jars/              # Java JARs
│   ├── gson-2.10.1.jar
│   └── commons-lang3-3.12.0.jar
└── credentials.json   # Registry + GitHub auth tokens

When working inside a project, fglpkg can also install to a local .fglpkg/ directory:

myproject/
├── fglpkg.json
├── .fglpkg/           # Local package install (add to .gitignore)
│   ├── packages/
│   └── jars/
└── ...

Local vs Global (Context-Aware)

fglpkg automatically detects whether to use local or global package storage:

Current directory has... Default behavior
.fglpkg/ directory Local (.fglpkg/)
fglpkg.json file Local (.fglpkg/)
Neither Global (~/.fglpkg/)

Override with --local / -l or --global / -g on install, remove, update, list, and env.

For shell profiles, always use --global so all installed packages are available regardless of directory:

eval "$(fglpkg env --global)"

fglpkg.json Format

For a project (consuming packages)
{
  "name": "myproject",
  "version": "1.0.0",
  "description": "My Genero BDL project",
  "author": "Jane Developer",
  "license": "MIT",
  "dependencies": {
    "fgl": {
      "myutils": "^1.0.0",
      "dbtools": "2.1.0"
    },
    "java": [
      {
        "groupId": "com.google.code.gson",
        "artifactId": "gson",
        "version": "2.10.1"
      }
    ]
  }
}
For a package (publishing to registry)
{
  "name": "poiapi",
  "version": "1.0.0",
  "description": "POI API for Genero BDL",
  "author": "Jane Developer",
  "license": "MIT",
  "root": "com/fourjs/poiapi",
  "genero": "^4.0.0",
  "main": "PoiApi.42m",
  "programs": ["PoiConvert", "PoiMerge"],
  "dependencies": {
    "java": [
      {
        "groupId": "org.apache.poi",
        "artifactId": "poi",
        "version": "5.2.3"
      }
    ]
  }
}
Manifest Fields
Field Required Description
name Yes Package name (used as the registry identifier)
version Yes Semver version string
description No Short description
author No Author name
license No License identifier (e.g., MIT, Apache-2.0)
repository No Source repository URL
main No Primary .42m entry point
genero No Genero BDL version constraint (e.g., ^4.0.0)
root No Base directory for package files when publishing (default .)
files No Glob patterns for files to include in the zip (default ["*.42m", "*.42f", "*.sch"])
bin No Command name to script path mappings (e.g., {"migrate": "scripts/migrate.sh"})
docs No Glob patterns for documentation files to include (e.g., ["README.md", "docs/**/*.md"])
dependencies.fgl No BDL production package dependencies (name -> version constraint)
dependencies.java No Java JAR production dependencies (Maven coordinates)
devDependencies No Test / tooling deps (fgl + java), skipped with --production
optionalDependencies No Attempted like prod, failures emit a warning instead of aborting
programs No List of module names with MAIN blocks (e.g., ["PoiConvert"])
scripts No Custom script definitions

Environment Variables

Variable Purpose
FGLPKG_HOME Override default ~/.fglpkg home
FGLPKG_REGISTRY Override default registry URL
FGLPKG_PUBLISH_TOKEN Admin/publish token (bypasses credentials file)
FGLPKG_GITHUB_TOKEN GitHub PAT for package uploads/downloads (private repo)
FGLPKG_GITHUB_REPO GitHub owner/repo for package storage (e.g., 4js-mikefolcher/fglpkg-packages)
FGLPKG_GENERO_VERSION Override Genero version detection
FGLLDPATH Auto-managed by fglpkg env (prepends, preserves existing value)
CLASSPATH Auto-managed by fglpkg env (prepends, preserves existing value)

Usage

# Package management
fglpkg init                              # Initialise fglpkg.json interactively
fglpkg install                           # Install deps (auto-detects local vs global)
fglpkg install myutils                   # Add + install latest version
fglpkg install myutils@1.2.0             # Add + install specific version
fglpkg install tester -D                 # Add under devDependencies
fglpkg install telemetry -O              # Add under optionalDependencies
fglpkg install --production              # Skip devDependencies (CI / deploy)
fglpkg install --global                  # Force install to ~/.fglpkg/
fglpkg install --local                   # Force install to .fglpkg/
fglpkg remove myutils                    # Remove a package (any scope)
fglpkg update                            # Re-resolve and update all dependencies
fglpkg list                              # List installed packages
fglpkg env                               # Print export statements (auto-detects scope)
fglpkg env --global                      # Print exports for all global packages
fglpkg env --gst                         # Print in Genero Studio format
fglpkg search json                       # Search registry
fglpkg bdl <pkg> <module> [args...]      # Run a BDL program from a package
fglpkg bdl --list                        # List available BDL programs

# Publishing
fglpkg publish                           # Publish current package to registry
fglpkg unpublish pkg@1.0.0               # Remove a published version

# Authentication
fglpkg login                             # Save registry + GitHub credentials
fglpkg logout                            # Remove saved credentials
fglpkg whoami                            # Show current authenticated user

# Registry configuration (admin)
fglpkg config github-repos list          # List configured GitHub repos
fglpkg config github-repos add o/r       # Add a GitHub package repo
fglpkg config github-repos remove o/r    # Remove a GitHub package repo

# Package ownership
fglpkg owner list <pkg>                  # List package owners
fglpkg owner add <pkg> <user>            # Add a package owner
fglpkg owner remove <pkg> <user>         # Remove a package owner

# Token management (admin)
fglpkg token create <user>               # Create a user + token
fglpkg token revoke [<user>]             # Revoke a token
fglpkg token rotate                      # Rotate your own token

# Workspaces
fglpkg workspace init [paths...]         # Initialise a monorepo workspace
fglpkg workspace add <path>              # Add a member to the workspace
fglpkg workspace list                    # List workspace members
fglpkg workspace info                    # Show workspace details

# Scripts (bin)
fglpkg run --list                        # List all available commands
fglpkg run <command> [-- args...]        # Run a script from an installed package

# Documentation
fglpkg docs <package>                    # List documentation files
fglpkg docs <package> <file>             # Display a documentation file

# Misc
fglpkg version                           # Print version and build info
fglpkg help                              # Show help

Running the Registry Server

# Build the registry binary
go build -o fglpkg-registry ./cmd/registry

# Start the server
export FGLPKG_PUBLISH_TOKEN=my-secret-token
./fglpkg-registry \
  --addr :8080 \
  --data /var/lib/fglpkg-registry \
  --base-url https://registry.example.com

# Point fglpkg clients at your registry
export FGLPKG_REGISTRY=https://registry.example.com
Registry API
Method Path Description
GET /packages/:name/versions List all versions, Genero constraints, and available variants
GET /packages/:name/:version Full package metadata (append ?genero=4 to select a variant)
GET /packages/:name/:version/download Download the zip (or redirect to external storage)
POST /packages/:name/:version/publish Publish a new version or variant (auth required)
DELETE /packages/:name/:version/unpublish Remove a published version (auth required)
GET /packages/:name/owners List package owners
POST /packages/:name/owners Add a package owner (auth required)
DELETE /packages/:name/owners/:user Remove a package owner (auth required)
GET /config Registry configuration (GitHub repos)
POST /config/github-repos Add a GitHub repo (admin only)
DELETE /config/github-repos/:owner/:repo Remove a GitHub repo (admin only)
POST /auth/token Create a user + token (admin only)
DELETE /auth/token Revoke a token
POST /auth/token/rotate Rotate own token
GET /auth/whoami Identify current token
GET /auth/users List all users (admin only)
GET /search?q=<term> Search by name or description
GET /health Liveness probe
Publishing a Package

Package zips are stored as GitHub Release assets on a private repository. The registry server on Fly.io stores only metadata (no zip files).

First, an admin configures the GitHub repo on the registry (one-time setup):

fglpkg config github-repos add 4js-mikefolcher/fglpkg-packages

Then any authenticated user can publish:

# Log in (prompts for both registry token and GitHub token)
fglpkg login

# Publish
fglpkg publish

The CLI automatically fetches the GitHub repo from the registry config. You can override it with FGLPKG_GITHUB_REPO if needed.

The publish flow:

  1. Builds a zip from the directory specified by root (or .), collecting files matching files patterns (default: *.42m, *.42f, *.sch)
  2. Uploads the zip as a GitHub Release asset to the private packages repo
  3. Registers metadata (description, checksum, download URL, dependencies) with the registry

GitHub token requirements:

  • Publishers need a fine-grained PAT with Contents: Read and write on the packages repo
  • Consumers (installers) need a fine-grained PAT with Contents: Read on the packages repo
Genero Version Variants

Each package version can have multiple builds, one per Genero major version. When you publish, fglpkg detects your local Genero version and tags the upload as a variant:

# On a Genero 4.x machine
fglpkg publish    # uploads poiapi-1.0.0-genero4.zip

# On a Genero 6.x machine
fglpkg publish    # uploads poiapi-1.0.0-genero6.zip

Both variants live under the same release (poiapi-v1.0.0) as separate assets. When a consumer runs fglpkg install, the resolver automatically selects the variant matching their local Genero major version.

Registry Storage Layout

The registry server stores only metadata. Package zips are hosted on GitHub Releases.

/var/lib/fglpkg-registry/
├── index.json                  # global package catalogue
├── config.json                 # registry configuration (GitHub repos)
├── auth.json                   # user tokens and ownership
└── packages/
    └── myutils/
        └── meta.json           # all version records + variant info

Package zips are stored as GitHub Release assets:

GitHub Release: myutils-v1.0.0
├── myutils-1.0.0-genero4.zip  # variant for Genero 4.x
└── myutils-1.0.0-genero6.zip  # variant for Genero 6.x

Releases

Releases are automated via GitHub Actions. Push a tag to create a release with binaries for all platforms:

git tag v1.0.0
git push origin v1.0.0

Pre-built binaries are available at GitHub Releases.

Directories

Path Synopsis
cmd
fglpkg command
registry command
internal
checksum
Package checksum provides SHA256 verification for downloaded files.
Package checksum provides SHA256 verification for downloaded files.
cli
credentials
Package credentials manages per-registry authentication tokens stored in ~/.fglpkg/credentials.json.
Package credentials manages per-registry authentication tokens stored in ~/.fglpkg/credentials.json.
env
genero
Package genero detects the installed Genero BDL runtime version and provides compatibility checking against generoConstraint expressions.
Package genero detects the installed Genero BDL runtime version and provides compatibility checking against generoConstraint expressions.
github
Package github provides helpers for uploading and downloading fglpkg package zips via GitHub Releases on a shared repository.
Package github provides helpers for uploading and downloading fglpkg package zips via GitHub Releases on a shared repository.
hooks
Package hooks executes the declarative lifecycle steps declared in a manifest's "hooks" field.
Package hooks executes the declarative lifecycle steps declared in a manifest's "hooks" field.
lockfile
Package lockfile manages fglpkg.lock — the reproducible install record.
Package lockfile manages fglpkg.lock — the reproducible install record.
registry/server
Package auth implements token-based authentication and package ownership for the fglpkg registry server.
Package auth implements token-based authentication and package ownership for the fglpkg registry server.
resolver
Package resolver implements transitive dependency resolution for fglpkg.
Package resolver implements transitive dependency resolution for fglpkg.
semver
Package semver implements semantic versioning parsing, comparison, and constraint matching for fglpkg.
Package semver implements semantic versioning parsing, comparison, and constraint matching for fglpkg.
workspace
Package workspace implements fglpkg workspace support — a way to manage multiple related BDL packages in a single repository (monorepo).
Package workspace implements fglpkg workspace support — a way to manage multiple related BDL packages in a single repository (monorepo).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL