# lgx A package and project manager for [let-go](https://github.com/nooga/let-go): git-based dependency manager, runner, build tool, test runner, scaffolder, and task runner, in one binary. ```sh lgx new myapp # scaffold a project cd myapp lgx install # install deps from lgx.edn lgx run # fetch deps, run :main lgx nrepl # run nrepl lgx build # bundle a standalone binary lgx test # run tests under test/ lgx # run a custom task from lgx.edn ``` ## Requirements - [`lg`](https://github.com/nooga/let-go) >= `1.11.0` on `PATH` (or pointed to by `LGX_LG`). Install it with `brew install nooga/tap/let-go`. - `git` on `PATH`. (lgx uses it to clone, fetch, and check out deps) ## Installation Prebuilt binaries for `linux_amd64`, `linux_arm64`, `darwin_amd64`, and `darwin_arm64` are attached to each [GitHub Release](https://github.com/abogoyavlensky/lgx/releases). There are a few ways to install `lgx`. ### Homebrew Works on macOS and Linux: ```sh brew install abogoyavlensky/tap/lgx ``` This installs lgx only. Install let-go (`lg`) separately with `brew install nooga/tap/let-go`. ### With [mise](https://mise.jdx.dev) ```sh mise use -g github:abogoyavlensky/lgx@latest ``` Or pin per project in `.mise.toml`: ```toml [tools] "github:nooga/let-go" = "latest" "github:abogoyavlensky/lgx" = "latest" ``` ### Install script Installs the latest release to `~/.local/bin/lgx`: ```sh curl -fsSL https://raw.githubusercontent.com/abogoyavlensky/lgx/master/scripts/install.sh | bash ``` See the [script's README](./scripts/README.md) for options. ## Quickstart Create a new project and run it: ```sh lgx new hello cd hello lgx run ``` `lgx new` scaffolds from the [base template](https://github.com/abogoyavlensky/lgx-template-base); `-t/--template` selects another (see [`lgx new` templates](#lgx-new-templates)). `lgx run` resolves `:main` from `lgx.edn`, fetches any deps under `$LGX_HOME/gitlibs/`, then execs `lg`. ## Commands | Command | What it does | | --- | --- | | `lgx new [-t ]` | Scaffold a new let-go project into `./` from a built-in template (`base`, `cli`, `lib`) or a git URL. | | `lgx install` | Fetch deps from `:deps` into the gitlibs cache. Idempotent. Useful for editor navigation. | | `lgx run [args...]` | Run `:main` through `lg` with deps on the source path. Put a script or `lg` flags before `--` to drive `lg` yourself; program args go after `--`. With no `:main` and no script, errors (use `lgx repl` for a REPL). | | `lgx repl` | Start `lg`'s built-in REPL with the project's deps on the source path. Auto-applies the `:dev` and `:test` contexts when defined. | | `lgx nrepl [--port N]` | Start a REPL with an nREPL server on a free OS-assigned port (or `N`). Writes `.nrepl-port`. Auto-applies the `:dev` and `:test` contexts when defined. | | `lgx build [args...]` | Bundle `:main` into `:targets/:bin/:out` in `lgx.edn` via `lg -b`. | | `lgx test [file]` | Run `*_test.lg` / `*_test.cljc` / `*_test.clj` files under `test/`. With ``, run just that file. | | `lgx [args...]` | Run a custom task defined under `:tasks` in `lgx.edn`, binding any declared positional `:args`. | | `lgx` or `lgx help` | Show usage, including project tasks if an `lgx.edn` is found. | | `lgx version` | Print version. | Options: - `--with ` applies one or more named [contexts](#contexts) to the command. Works with `run`, `repl`, `nrepl`, `build`, `test`, `install`, and user tasks; on a task it unions with the task's own `:with`. - `--verbose` prints the resolved `lg` invocation before running (applies to `run`, `repl`, `nrepl`, `build`, `test`, and user tasks). It first prints a `+ lg ()` line naming the `lg` it resolved - the version from `lg -v` and the full binary path, which reflects an `LGX_LG` override. It also prints a `+ env …` line listing the env vars lgx sets. Both options go before the subcommand: `lgx --with dev,test run`. `lgx run`, `repl`, `nrepl`, `build`, `test`, and tasks find the nearest `lgx.edn` by walking up from the current directory. ### `lgx new` templates `lgx new` takes `-t`/`--template` with a built-in template name or a git URL: ```sh lgx new myapp # base template (the default) lgx new myapp -t cli # built-in template by name lgx new myapp -t https://github.com/user/my-template ``` Built-in templates are pinned to a latest revision: | Name | Repo | Purpose | | --- | --- | --- | | `base` | [lgx-template-base](https://github.com/abogoyavlensky/lgx-template-base) | Minimal let-go app. | | `cli` | [lgx-template-cli](https://github.com/abogoyavlensky/lgx-template-cli) | Command-line app skeleton. | | `lib` | [lgx-template-lib](https://github.com/abogoyavlensky/lgx-template-lib) | Library project skeleton. | A URL template uses the repo's latest default-branch HEAD and caches the checkout by sha under `$LGX_HOME/templates/`. Template URLs must be `https://host/owner/repo` (or `file:///path/to/repo` for local development); SSH forms like `git@host:owner/repo` are not supported. To make a repo a template, put the literal token `projectname` in paths and file contents wherever the project name belongs; `lgx new` replaces it with the underscored name (`my_app`) in paths and the hyphenated name (`my-app`) in contents. ### `lgx run` details `lgx run` runs `:main`. Put a script or `lg` flags before `--` and you drive `lg` yourself (`:main` isn't added); your program's args go after `--` and arrive in `*command-line-args*` (requires `lg` >= 1.11.0). With no `:main` and no script it errors: set `:main`, name a script, or start [`lgx repl`](#lgx-repl-details). It also sets `LGX_RUN=1` in the spawned process, so a tool can tell it runs under `lgx run` (dev) vs. as a bundled binary. The spawned `lg` inherits lgx's stdio, so live output and interactive programs (REPL, prompts) work.
Argument forms - `lgx run` -> `lg
` (`*command-line-args*` is `nil`). - `lgx run -- foo bar` -> `lg
foo bar` -> `*command-line-args*` is `("foo" "bar")`. - `lgx run other.lg` -> `lg other.lg` (explicit script, no `:main`). - `lgx run other.lg -- bar` -> `lg other.lg bar` -> `*command-line-args*` is `("bar")`. - `lgx run -e '(...)'` -> `lg -e '(...)'` (no `:main`). - `lgx run -- a -- b` -> `*command-line-args*` is `("a" "--" "b")` (only the first `--` is the separator).
### `lgx repl` details `lgx repl` opens `lg`'s built-in REPL with the project's deps and `:paths` on the source path, no script and no `:main`. It auto-applies the `:dev` and `:test` contexts, exactly like `lgx nrepl`; the difference is that `repl` binds no port and writes no `.nrepl-port`, so it is the zero-footprint choice for a quick session. Reach for `lgx nrepl` when an editor needs to connect. It takes no arguments of its own (`--with`/`--verbose` are the usual leading options). For a scratch script or `lg` flags with your deps on the path, use `lgx run