Skip to content

Latest commit

 

History

History
352 lines (253 loc) · 9.68 KB

File metadata and controls

352 lines (253 loc) · 9.68 KB

Winn CLI

Install

# macOS
brew tap gregwinn/winn && brew install winn

# Linux (curl)
curl -fsSL https://winn.ws/install.sh | bash

# Ubuntu / Debian
curl -fsSL https://winn.ws/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/winn.gpg
echo "deb [signed-by=/usr/share/keyrings/winn.gpg] https://gregwinn.github.io/apt.winn.ws stable main" \
  | sudo tee /etc/apt/sources.list.d/winn.list
sudo apt update && sudo apt install winn

# Fedora / RHEL
sudo dnf config-manager --add-repo https://gregwinn.github.io/rpm.winn.ws/winn.repo
sudo dnf install winn

Quick Reference

Command Shortcut Description
winn new <name> Create a new project
winn run <file> r Compile and run a file
winn start [module] s Start project (keeps VM alive)
winn test [file] t Run tests
winn watch [--start] w Watch + hot-reload
winn console con Interactive REPL
winn compile [file] c Compile .winn files
winn fmt [file] f Format code (--check for CI)
winn lint [file] l Static analysis linter
winn docs [file] d Generate API docs
winn lsp Start language server (stdio)
winn create <type> g Generate code (model, migration, ...)
winn migrate Run database migrations
winn rollback Rollback migrations
winn task <name> Run a project task
winn add <package> Install a package
winn remove <package> Remove a package
winn packages List installed packages
winn install Install all from package.json
winn deps Manage Erlang dependencies
winn bench <file> Load testing
winn metrics Live metrics dashboard
winn release Build production release
winn version -v Print version
winn help -h Show help

Command Details

winn new <name> [--api | --minimal]

Create a new project. Three modes available:

winn new my_app              # full scaffold (default)
winn new my_app --api        # API project with router + health endpoint
winn new my_app --minimal    # just src/ and rebar.config

Default creates: src/, test/, config/, db/migrations/, README.md, .env.example, .gitignore, package.json.

--api adds a router with use Winn.Router, a /api/health endpoint, a health controller, and Server.start in main().

--minimal creates only src/<name>.winn, rebar.config, .gitignore, and package.json.

winn compile [file]

Compile .winn files to .beam bytecode in ebin/.

winn compile                   # all files in src/
winn compile src/my_app.winn   # single file

winn run <file>

Compile and run a single file. Calls main() and exits.

winn run src/hello.winn

winn start [module]

Compile all files, start OTP apps, call main(), keep the VM alive. Use for servers and long-running services.

winn start              # auto-detect main module
winn start my_app       # specify module

winn test [file]

Run tests written with use Winn.Test. Discovers test_* functions automatically.

winn test                       # all tests in test/
winn test test/math_test.winn   # specific file
module MathTest
  use Winn.Test

  def test_addition()
    assert(1 + 1 == 2)
  end

  def test_equality()
    assert_equal("hello", "hello")
  end
end

winn watch

Watch files for changes, hot-reload via BEAM code swap, show a live terminal dashboard.

winn watch              # watch and recompile
winn watch --start      # watch + start the app

winn create <type> / winn c

Generate code from templates. winn c is shorthand.

winn create model User name:string email:string
# => src/models/user.winn

winn create migration CreateUsers name:string
# => db/migrations/TIMESTAMP_create_users.winn

winn create task db:seed
# => src/tasks/db_seed.winn

winn create router Api
# => src/controllers/api_controller.winn  (module ApiController)

winn create scaffold Post title:string body:text
# => src/models/post.winn, src/controllers/post_controller.winn, test/post_test.winn

Scaffold generates model + CRUD controller + test file.

winn migrate

Run pending database migrations from db/migrations/*.winn.

winn migrate              # run all pending
winn migrate --step 2     # run next 2
winn migrate --status     # show applied vs pending

winn rollback

Rollback database migrations.

winn rollback             # rollback last
winn rollback --step 3    # rollback last 3

winn task <name>

Run project tasks. Rails-style colon syntax.

winn task db:seed
winn task db:migrate

Tasks are modules with use Winn.Task and a run/1 function in src/tasks/.

winn add <package>

Install a Winn package.

winn add redis                        # from gregwinn/winn-redis
winn add github:user/winn-stripe      # from any GitHub repo

winn remove <package>

Remove an installed package.

winn remove redis

winn packages

List installed packages with version and module name.

winn install

Install all packages from package.json.

Available packages:

Package Install Description
winn-redis winn add redis Redis client
winn-mongodb winn add mongodb MongoDB client
winn-amqp winn add amqp RabbitMQ/AMQP client

winn fmt [file]

Format Winn source files for consistent code style.

winn fmt                   # format all .winn files in src/ (or current dir)
winn fmt src/app.winn      # format a specific file
winn fmt --check           # check formatting without modifying (exits 1 if unformatted)

winn lint [file]

Run static analysis on Winn source files.

winn lint                  # lint all .winn files in src/ (or current dir)
winn lint src/app.winn     # lint a specific file

Rules checked:

Rule Category Description
unused_variable Correctness Variable assigned but never referenced (prefix with _ to ignore)
unused_import Correctness Import directive with no calls to that module
unused_alias Correctness Alias directive with no calls using that alias
function_name_convention Style Function names must be snake_case (trailing ? allowed)
module_name_convention Style Module names must be PascalCase
redundant_boolean Simplification x == true can be simplified to x
empty_function_body Correctness Function with no body returns nil silently
pipe_into_literal Correctness Pipe |> into a non-callable value
single_pipe Style Single |> with no chain — consider a regular call
large_function Complexity Function body exceeds 50 expressions

Exits with code 0 if no warnings, code 1 if warnings found.

winn lsp

Start the Language Server Protocol server on stdio. Provides IDE integration for editors that support LSP (VS Code, Neovim, Helix, etc.).

winn lsp   # starts language server on stdio

Capabilities:

  • Diagnostics — inline compile errors from lexer, parser, semantic, and transform phases. Triggered on file open, change, and save.
  • Autocomplete — dot-triggered completions for 14 modules: IO, String, Enum, List, Map, Server, HTTP, JSON, Logger, File, Repo, System, Task, Regex, Agent.

VS Code integration: In the Winn VS Code extension, set "winn.lsp.command": "winn lsp".

winn docs [file]

Generate Markdown API docs with a Mermaid module dependency graph.

winn docs                 # all src/*.winn → doc/api/
winn docs src/api.winn    # single file

winn bench <file>

Run load tests with concurrent BEAM workers. Reports P50/P95/P99 latency.

winn bench bench/api_bench.winn

winn metrics

Live terminal dashboard showing HTTP stats, BEAM health, and custom metrics.

winn release

Build a production OTP release.

winn release              # build release
winn release --docker     # generate Dockerfile

winn deps

Manage Erlang dependencies (lower-level than winn add).

winn deps list
winn deps add cowboy 2.12.0
winn deps remove cowboy
winn deps install

winn console

Interactive REPL with variable persistence.

winn version

winn version    # => winn 0.7.0
winn -v
winn --version

Exit Codes

Code Meaning
0 Success
1 Compilation error, runtime error, or unknown command