Repository navigation
hecatron 0.4.0
-
A fast binary: installing a release also installs the Go core for
your machine (macOS and Linux, x86_64 and arm64), checksum-verified, and
hctruns it:--versionandlistanswer in about a millisecond
(80 ms before, on a 51-language project), and help,list,envand the
run commands no longer depend on the system's bash (macOS's 3.2). The
run commands take--output human|agent|json|ci(orHECATRON_OUTPUT):
agent output is a summary line and only the failures with their key
error lines; exit status 3 means a toolchain is missing. The rest still
runs through the scripts.HECATRON_NO_GO=1keeps to the scripts. -
Fixes on macOS's bash 3.2: every run command's help and
hct doctorno longer fail with "unbound variable" in a repository with no
languages (which the binary avoids altogether). -
.NET runs the SDK it should: a version the project's config names
runs exactly that SDK, each version in its own view of/opt/dotnet; a
version a GitHub workflow names is installed but, assetup-dotnet
does, the newest SDK runs unless aglobal.jsonpicks one, and
hecatron doctornow says which. Downloadingdotnet-install.sh
retries a dropped connection. -
Installing everything fetches dependencies last: with no languages
named,hecatron installinstalls every toolchain first, then fetches
dependencies once, so one language's fetch that needs another's
toolchain (apreparescript running Ruby) no longer fails. -
Perl runs a project's own Makefile test target, which may set what
its tests need (AUTHOR_TESTING): cucumber/tag-expressions runs 169
tests through it, where hecatron'sproveran 68. -
hecatron initskips a package with no test script for a JavaScript
or TypeScript implementation (a JSON-schema package beside the real
one), saying why. -
A generated image fails when its PowerShell modules didn't install,
instead of shipping without Pester. -
Instructions for AI agents:
hct initwrites a short section to
AGENTS.md(and has an existingCLAUDE.mdload it);--no-agentsskips
it.hct help agentsprints a compact reference written for agents. -
No setup step: in a git repository without
.hecatron/config.json,
every command works on whathct initwould detect, remembered inside
.git/until the tracked files change; nothing is written to the working
tree.hct initsaves it, to commit and adjust. -
hct lintnow fails on unformatted code. It runs each language's
format check (below) after its linter, where the linter doesn't check
formatting already, so a project whose code isn't formatted the way its
formatter says will seelintfail. Runhct formatonce, or turn the
check off in.hecatron/config.jsonwith"lint": {"format": false}(or
{"format": {"haskell": false}}for one language). See
docs/format.md. -
hecatron outdated: lists each component's direct dependencies that
have a newer version, from each ecosystem's own report (npm, pnpm, Yarn,
uv,go list -u -m, Cargo's dry-run update, Bundler, Composer, the .NET
SDK, Hex, pub, Maven's versions plugin, Gradle's Versions plugin where a
build applies it, cabal), with current, wanted and latest versions.
Report-only unless--fail;--jsonprints one array. See
docs/outdated.md. -
hecatron deps: fetches every component's dependencies with its
ecosystem's tool, held to the lock file where there is one: npm, pnpm,
Yarn or Bun's frozen install,uv sync --locked, Bundler frozen,
composer install,dotnet restore --locked-mode,go mod download,
cargo fetch --locked,mix deps.get,pub get --enforce-lockfile,
swift package resolve, Maven'sdependency:go-offline, Gradle, sbt,
Stack or cabal, and more. Languages without a dependency manager say so.
The test, lint and build hooks that install missing dependencies, and the
installers, now do it the same way, so pnpm, Yarn, Bun, Bundler, Dart
and Shards installs no longer change a lock file: one that's out of
date fails, asnpm cialready did. -
hecatron format: rewrites every component's code with its
language's formatter, using the project's own configuration: gofmt,
rustfmt, Ruff (or Black),dotnet format,mix format,dart format,
zig fmt, swift-format, elm-format..., and where the project configures
one, Prettier or Biome, RuboCop or Standard, PHP CS Fixer or Pint,
Spotless, ktlint or scalafmt through the build, clang-format, StyLua,
perltidy, Fourmolu or Ormolu, Air, cljfmt, erlfmt, JuliaFormatter and
ocamlformat.--checkchanges nothing and lists the files it would
change. The installers add the formatters a toolchain doesn't ship, at
pinned versions. -
hecatron audit: checks every component's dependencies for known
vulnerabilities with each ecosystem's auditor (npm, pnpm, Yarn, Bun,
pip-audit, govulncheck, bundler-audit, Composer, the .NET SDK, and
OSV-Scanner for the rest), fails at--fail-on(default high), and takes
accepted risks with a reason and an expiry date. See
docs/audit.md. -
Old checkouts get the toolchains of their day: when a repository's last
commit is over a year old, each language's version becomes the release
that was current then, unless the project pins an exact one. A 2021
checkout gets the Node.js and JDK it was tested with instead of today's,
which can no longer build or run it.HECATRON_AS_OFsets the date or
turns this off;hecatron doctorsays when it applies.
A weekly workflow keeps the release dates this uses current. -
CI workflows and Maven builds say how new a toolchain may be: with no
pin file, the versions a project's GitHub Actions setup steps use, and a
Maven build's Java source level, hold the default back. -
JavaScript components choose their Node.js version like TypeScript's.
-
Python follows the versions a project supports: with no pin file, a
component whose classifiers stop at an older Python than the default
(Avro's at 3.14) gets that line's newest release, since compiled
dependencies often lag a new Python.hecatron doctorsays when. -
elm-review is on PATH: global npm commands Elm installs are all linked
onto PATH, now that Node.js comes from its official builds. -
CMake builds run fewer compile jobs at once: one per CPU (or CPU
quota) but at most one per 2 GB of memory, so a large C++ project no
longer has its compilers killed for memory.CMAKE_BUILD_PARALLEL_LEVEL
still decides when set. -
A CMake subdirectory is built as part of its project: a component
whoseCMakeLists.txtcalls noproject()(one a parent's
add_subdirectory()pulls in) is configured from the nearest directory
above it that does, and its own tests run. -
CMake test options are the project's own: the test hook no longer
turns on a fetched dependency's test options, nor valgrind or
large-memory ones, and an option whose setup is missing is left off
instead of failing the configure. A project that registers no CTest
tests and runs them from acheckorteststarget gets that target. -
C and C++ installers find more of what a CMake build needs:
pkg_check_modules()andpkg_search_module()lookups, headers looked
for by hand (gtest/gtest.h), filesinclude()d from outside the
component, the enclosing project's own lookups, and more libraries (GLib,
RE2, ICU, Jansson, Snappy, zstd, LZ4, libevent, flex, bison...). -
Perl installs Module::Install and the extensions a
Makefile.PL
written with it names (configure_requires), which a checkout doesn't
bundle, and installs the CPAN dependencies aMakefile.PLorBuild.PL
declares, as it did acpanfile's. -
Dart installs Flutter (3.47.8) where a component is a Flutter package,
and fetches its packages withflutter pub get; the doctor reports it
missing. The test hook says so when a package has notest/directory. -
JVM builds get the JDKs they ask for: the JVM installers install the
JDKs a Gradle or Maven toolchain names, and a build whose Gradle wrapper
(before 9.1) or Kotlin compiler (before 2.3) can't run on the default
JDK runs on the newest LTS JDK it supports, which they install too. -
Python installs a C compiler on Linux, for dependencies that build a
C extension from source. -
Default hooks find a build that isn't in the language's directory:
above it in the project (pulumi'ssdk/goin the modulesdk/go.mod, a
rootPackage.swift, CMake project or Gradle build), or in directories
below it, run in each (several crates underrust/, a solution in
csharp/src/), or a root Makefile's target named for the directory
(check_cxx). -
Node.js uses the project's package manager: the hooks and installers
run pnpm, Yarn or Bun whenpackageManageror the lockfile says so (pnpm
and Yarn through Corepack), so a pnpm or Yarn workspace installs instead of
failing onworkspace:*. -
Toolchain versions for .NET (C#, F#, VB.NET): a pinned default SDK
(10.0.403 LTS, the 10.0.4xx feature band), or the one a component's
global.json asks for, installed side by side with Microsoft's
dotnet-install.sh into/opt/dotnet(per-user on macOS) rather than the
distribution's package, which holds one feature band; the runtimes older
target frameworks need go there too. A newer band's analyzers no longer
fail with CS9057 on Ubuntu's 10.0.1xx compiler. -
Toolchain versions for PHP: a pinned default (PHP 8.5), or the line a
component's.php-version, composer.jsonconfig.platform.php,
.tool-versionsor mise asks for, installed side by side from Ondřej
Surý's packages (his PPA on Ubuntu, packages.sury.org on Debian) or
Homebrew's shivammathur/php tap, with one Composer for all. The doctor
reports a component whose PHP is older than its composer.lock needs. -
Toolchain versions for Ruby: a pinned default (Ruby 4.0.9), or the
version a component's.ruby-version,.tool-versionsor mise asks for,
built side by side by ruby-build into/opt/ruby/<version>(per-user on
macOS), each with its own Bundler. Ruby no longer comes from apt, whose
3.2 is too old for many gems. -
global.json's
rollForwardcounts: a .NET SDK pin of 8.0.100 with
latestFeatureasks for the newest 8.0 SDK, and withlatestMajorthe
newest 8;.php-versionand composer.json'sconfig.platform.phppin
PHP. -
Rust repairs an interrupted install: a rustup left with no default
toolchain (an install killed mid-download) is reported by the doctor and
fixed by the installer. -
docs/languages.md: every language with a link to
its home, a one-line description, and the build systems, test runners and
linters its default hooks use, generated from the definitions.