Skip to main content

MAHKRAB CLI tool

Project description

MahkrabCLI

MahkrabCLI installs the mk command: a lightweight source-file runner and compile-and-run helper for small files and small projects.

It gives you one command shape across many languages:

mk hello.py
mk main.c -r
mk src/app.js
mk init main.py
mk run
mk build
mk config
mk doctor

The goal is to reduce friction when switching between languages without turning the tool into a full build system.

Documentation

These links use GitHub URLs so they remain useful when this README is rendered on PyPI.

Installation

Install from PyPI:

pip install mahkrab

Or install as an isolated CLI with pipx:

pipx install mahkrab

Check the installation:

mk --version
mk --help

Quick Start

Run a source file directly:

mk hello.py
mk src/app.js
mk main.c -r
mk hello

For compiled languages, -r / --run-on-compile compiles and then runs the result. Interpreted files run directly, so this option has no practical effect there. Targets with no extension, such as hello, are treated as runnable binaries.

Create a project config when you want repeatable commands:

mk init src/main.c --lang c --run-on-compile

This creates .mkconfig/mkconfig.toml:

entry = "src/main.c"
lang = "c"
os = "linux"
build_dir = "build"
run_on_compile = true

Then run:

mk run
mk build

mk run reads the configured entry and runs it. mk build reads the same entry and compiles it without running the output.

Command Forms

Command Purpose
mk <file> Run, interpret, compile, or execute a direct target.
mk init [file] Create .mkconfig/mkconfig.toml for project commands.
mk run Run the configured entry from a Mahkrab config file.
mk build Compile the configured entry without running it.
mk config Show the resolved config file and read or update supported config keys.
mk doctor Diagnose compiler and interpreter availability.

The bare names init, run, build, config, and doctor are reserved subcommands. If you have files with those exact names, use an explicit path:

mk ./init
mk ./run
mk ./build
mk ./config
mk ./doctor

Common Options

Option Purpose
--config <file> Use a specific config file. If a directory is given, mk looks for supported config names inside it.
--cwd <dir> Run as if mk started from another working directory.
-o, --output <file> Set the compiled output path or name.
--build-dir <dir> Set the build output directory. Defaults to build.
--python <python> Override the Python interpreter for Python files.
--lang <language> Force a language handler instead of using the file extension.
--tool <tool> Override the compiler or interpreter executable for the selected handler.
--compile-args ... Pass extra arguments to the compiler or interpreter.
--tool-args ... Alias for --compile-args.
--program-args ... Pass arguments to the script or compiled program.
-e, --explain Print the resolved execution plan before running.
-r, --run-on-compile Compile then run compiled languages.
-c, --clear Clear the terminal before running the action.
-h, --help Show command help.
-v, --version Show the installed version.

Examples:

mk main.cpp --build-dir out -o out/main -r
mk script.py --python python3.12
mk README.md --lang python --tool python3.12 --explain
mk app.go --compile-args "-trimpath" -r
mk main.c -r --program-args -- hello world
mk run --cwd ./examples
mk build --config ./examples/.mkconfig.toml

See the CLI reference for the full command and option reference.

Init

Use mk init to create a project config at .mkconfig/mkconfig.toml. The generated file is TOML and uses the same keys that mk run and mk build read at runtime.

mk init
mk init main.py
mk init --entry src/main.c --lang c --run-on-compile
mk init --os windows
mk init --build-dir out --output out/app
mk init --force

Options:

Option Purpose
--entry <file> Set the configured entry. A positional file, such as mk init main.py, does the same thing.
--lang <language> Write a lang override.
--os <os> Write os for doctor install hints. Supported values: linux, macos, windows.
--build-dir <dir> Write build_dir. Defaults to build.
-o, --output <file> Write output.
-r, --run-on-compile Write run_on_compile = true.
--force Overwrite an existing generated config.

If you do not provide an entry, mk init looks for common files such as src/main.py, main.py, src/main.c, or main.c. When it cannot infer one, it writes a short commented placeholder instead. By default it refuses to overwrite any discovered Mahkrab config and exits with status 2.

Config Files

mk run, mk build, and mk doctor can read TOML config from:

  • .mkconfig/mkconfig.toml
  • .mkconfig/.mkconfig.toml
  • .mkconfig.toml
  • .mkconfig

Example:

entry = "src/main.py"
cwd = "."
build_dir = "build"
output = "build/main"
python = "python3"
lang = "python"
os = "linux"
tool = "python3.12"
run_on_compile = true
clear = false
compile_args = ["-O"]
program_args = ["hello", "world"]

[doctor]
quiet = false
verbose = false

[env]
MY_VAR = "value"

Important rules:

  • entry is required for mk run and mk build.
  • Config files are TOML, including .mkconfig.
  • Relative config paths are resolved from the config file location.
  • CLI options take precedence over config values where both are available.
  • mk run always runs after compilation.
  • mk build always compiles only.

See the configuration guide for discovery rules, key-by-key reference, and precedence details.

Config Command

Use mk config to inspect the config file Mahkrab resolved and to read or update supported config keys without opening the TOML file manually. The output uses the normal coloured Mahkrab conventions.

mk config
mk config --config ./examples/.mkconfig.toml
mk config --entry
mk config --entry src/main.c
mk config --run-on-compile true
mk config --compile-args "-O2 -Wall"
mk config --env FOO=bar

Getter flags print the current configured value. The same flag becomes a setter when you pass a value:

  • --entry
  • --cwd
  • --build-dir
  • -o, --output
  • --python
  • --lang
  • --tool
  • -r, --run-on-compile
  • -c, --clear
  • --compile-args
  • --program-args

Boolean setters accept true, false, 1, or 0. --compile-args and --program-args accept a quoted shell-style string and store the parsed result as a TOML string array. --env KEY=VALUE adds or replaces entries in the [env] table.

Use --config <file> with mk config to read or update a specific config instead of the discovered one. If no config exists, mk config exits with status 2 and tells you to create one with mk init. Config updates preserve existing keys and rewrite the TOML file deterministically, but comments and original formatting may be normalized.

Passing Arguments

Use --compile-args for flags that belong to the compiler or interpreter:

mk main.c -r --compile-args "-O2 -Wall"
mk script.py --compile-args "-X utf8"

Use --program-args for values that belong to your program:

mk main.c -r --program-args -- hello world
mk script.py --program-args -- --name Ada

A bare -- also forwards the rest of the command line as program arguments:

mk main.c -r -- hello world

Assembly Support

Assembly targets on Unix-like systems now get the same kind of lightweight dependency help that C already has. Mahkrab scans supported assembly sources for obvious extern, call, include, and entry-point markers, then adds common compile or link flags automatically when it can.

This applies to:

  • NASM: .asm, .nasm
  • GNU assembler: .s, .S

Common cases now work without manually remembering linker flags for things such as C-runtime style main entry points, pthread, libm, SDL2, curl, sqlite3, OpenSSL, libpng, uuid, and X11 symbol usage. Preprocessed GNU assembler sources (.S) also reuse the existing C header-based mapping for common #include cases where that helps.

Examples:

mk hello.asm -r
mk hello.S --explain
mk math_demo.s -r

Manual --compile-args still work for custom assembler options or more advanced toolchain cases:

mk hello.S --compile-args "-Iinclude -g" -r

Doctor

mk doctor checks whether external tools are available on PATH or through configured overrides. It needs a configured entry, a direct target, --lang, or --all. When something is missing, doctor now prints a short OS-aware install hint so onboarding is more actionable. Doctor resolves the hint OS in this order: --os, then mkconfig os, then the current machine OS.

mk doctor
mk doctor src/main.py
mk doctor --lang python,c,cpp
mk doctor --all
mk doctor --os windows
mk doctor --quiet
mk doctor --json
mk doctor --verbose
mk doctor --languages

Doctor exits with:

  • 0 when all checked toolchains are available.
  • 1 when one or more checked toolchains are missing.
  • 2 for usage or configuration errors.

Normal terminal output keeps the coloured Mahkrab summary and adds a compact missing-tools section:

[MAHKRAB-CLI] Doctor
  config: /project/.mkconfig/mkconfig.toml
  cwd: /project
  doctor mode: default (default)
  hint os: linux (config file)
  C: missing
    - gcc: value=gcc source=default available=no path=-
  Missing tools:
    - gcc: languages=C install (linux)=sudo apt install build-essential
[MAHKRAB-CLI] - Unavailable checked languages: C

Use mk doctor --json for scripting, CI, or editor integrations. It prints JSON only, with no ANSI colour codes or extra text:

{
  "checked_languages": ["python", "c"],
  "checked_tools": [
    {
      "command": "gcc",
      "install_hints": {
        "windows": ["Install MSYS2 or Visual Studio Build Tools and add the compiler bin directory to PATH"]
      },
      "languages": ["c"],
      "recommended_hint": "Install MSYS2 or Visual Studio Build Tools and add the compiler bin directory to PATH",
      "resolved_path": null,
      "source": "default",
      "status": "missing",
      "tool": "gcc",
      "value": "gcc"
    }
  ],
  "detected_os": "linux",
  "ok": false,
  "os": "windows",
  "os_source": "config file"
}

--json composes with the normal doctor selectors such as --all, --lang, and --os. If --json is combined with human-oriented output flags like --quiet, JSON still wins so the output stays machine-readable.

Supported Languages

Language support is extension-driven and depends on the relevant external compiler or interpreter being installed.

Current handlers include Python, C, C++, Java, C#, JavaScript, TypeScript, Visual Basic, SQL, R, Pascal, Perl, Scratch, Fortran, Rust, MATLAB, Go, Assembly, PHP, Ada, Swift, Prolog, Kotlin, Classic Visual Basic, COBOL, Dart, Ruby, Lua, Bash, PowerShell, and extensionless binaries.

Use mk doctor --languages to list the language names and aliases accepted by doctor checks. The full extension and alias reference is in the CLI reference.

External Tools

MahkrabCLI does not bundle compilers or interpreters. By default, command names come from PATH, such as gcc, python, node, or javac.

Tool commands can also be overridden with environment variables:

export MAHKRAB_GCC=/usr/bin/gcc-14
export MAHKRAB_PYTHON=/usr/bin/python3.12
export MAHKRAB_NODE=/usr/bin/node

Common overrides include:

  • MAHKRAB_GCC, MAHKRAB_GPP, MAHKRAB_RUSTC, MAHKRAB_GO
  • MAHKRAB_JAVAC, MAHKRAB_JAVA
  • MAHKRAB_PYTHON, MAHKRAB_NODE, MAHKRAB_TS
  • MAHKRAB_SQLITE3, MAHKRAB_NASM, MAHKRAB_AS, MAHKRAB_LD

Current Limitations

  • MahkrabCLI is focused on convenience for standalone files and small projects.
  • Behavior depends on external tools being installed and available.
  • C/C++ dependency flag support is limited.
  • Assembly support currently targets Unix-like systems for NASM and GAS.

Development

Use the dev virtual environment in this repository:

python3 -m venv dev
. dev/bin/activate
python -m pip install -U pip
python -m pip install -e '.[dev]'
mk -h
pytest tests

MahkrabCLI supports Python 3.11 and newer.

Internal Layout

  • src/mahkrab/cli.py: CLI entry point.
  • src/mahkrab/tools/parser.py: command-line parsing.
  • src/mahkrab/tools/config.py: config parsing and runtime settings.
  • src/mahkrab/func/workflow.py: top-level run and build workflow.
  • src/mahkrab/func/plans.py: execution-plan creation and --explain output.
  • src/mahkrab/func/commands.py: command construction.
  • src/mahkrab/func/languages.py: language aliases, labels, and extension mapping.

Contributing

Issues and pull requests are welcome.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mahkrab-1.0.0.tar.gz (60.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mahkrab-1.0.0-py3-none-any.whl (57.3 kB view details)

Uploaded Python 3

File details

Details for the file mahkrab-1.0.0.tar.gz.

File metadata

  • Download URL: mahkrab-1.0.0.tar.gz
  • Upload date:
  • Size: 60.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for mahkrab-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a9992f3d1c337136f57c5434fdf884304e1fb64ba7f49d4261f891f7e646d6f0
MD5 8c92c8897a5a53889e31e2bffbff14c0
BLAKE2b-256 b6605049ba83ea23c0918841a89d538d22a9675618c4088156de8a6d69d73748

See more details on using hashes here.

File details

Details for the file mahkrab-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: mahkrab-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 57.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for mahkrab-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 05a45f4e8961b924a811cf742a7bb32bcd3e1143d82490d36c8e4e9505c9d238
MD5 6e6dc3cad4fece3fb525aab2efec0819
BLAKE2b-256 efacbccb7a93c8d18e9f7671da9a112c6e99b4ee22cd7a47334597bc573d3ade

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page