Skip to content

Latest commit

 

History

History
156 lines (122 loc) · 5.13 KB

README.md

File metadata and controls

156 lines (122 loc) · 5.13 KB

ghjk

ghjk /gk/ is a set of tools for managing developer environments and an attempt at a successor for asdf.

ghjk is part of the Metatype ecosystem. Consider checking out how this component integrates with the whole ecosystem and browse the documentation to see more examples.

Introduction

ghjk offers a unified abstraction to manage package managers (e.g. cargo, pnpm, poetry), languages runtimes (e.g. nightly rust, node@18, python@latest) and developer tools (e.g. pre-commit, eslint, protoc). It enables you to define a consistent environment across your dev environments, CI/CD pipelines and containers keeping everything well-defined in your repo and providing a great DX. This makes it especially convenient for mono-repos and long-lived projects. See Metatype and its ghjkfile for a real world example.

ghjk

Features

  • Install standalone posix programs or those found on different backends and registries
  • Tasks written in typescript
  • Soft-reproducible posix environments.
    • Declaratively compose envs for developer shells, CI and tasks.
    • Run tasks when entering/exiting envs.

Getting started

Before anything, make sure the following programs are available on the system.

  • git
  • tar (preferably GNU tar)
  • curl
  • unzip
  • zstd

Install the ghjk cli using the installer scripts like so:

curl -fsSL https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/install.sh | bash

Use the following command to create a starter ghjk.ts in your project directory:

ghjk init ts

Environments

Ghjk is primarily configured through constructs called "environments" or "envs" for short. They serve as recipes for making (mostly) reproducible posix shells.

import { file } from "https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/mod.ts";
// ports are small programs that install sowtware to your envs
import * as ports from "https://raw.github.com/metatypedev/ghjk/v0.3.0-rc.1/ports/mod.ts";

const ghjk = file({});

// NOTE: `ghjk.ts` files are expected to export this sophon object
// all the functions on the ghjk object  are ultimately modifying the 'sophon' proxy 
// object exported here.
export const sophon = ghjk.sophon;

// top level `install`s go to the `main` env
ghjk.install(ports.protoc());
ghjk.install(ports.rust());

// the previous block is equivalent to
ghjk.env("main", {
  installs: [ports.protoc(), ports.rust()],
});

ghjk
  .env("dev", {
    // by default, all envs are additively based on `main`
    // pass false here to make env independent.
    // or pass name(s) of another env to base on top of
    inherit: false,
    // envs can specify posix env vars
    vars: { CARGO_TARGET_DIR: "my_target" },
    installs: [ports.cargobi({ crateName: "cargo-insta" }), ports.act()],
  })
  // use env hooks to run code on activation/deactivation
  .onEnter(ghjk.task(($) => $`echo dev activated`))
  .onExit(ghjk.task(($) => $`echo dev de-activated`));

ghjk.env({
  name: "docker",
  desc: "for Dockerfile usage",
  // NOTE: env references are order-independent
  inherit: "ci",
  installs: [ports.cargobi({ crateName: "cargo-chef" }), ports.zstd()],
});

// builder syntax is also available
ghjk.env("ci")
  .var("CI", "1")
  .install(ports.opentofu_ghrel());

// each task describes it's own env as well
ghjk.task({
  name: "run",
  inherit: "dev",
  fn: () => console.log("online"),
});

ghjk.config({
  defaultBaseEnv: "main",
  defaultEnv: "main",
  // by default, nodejs, python and other runtime
  // ports are not allowed to be used
  // during the build process of other ports.
  // Disable this security measure here.
  enableRuntimes: true,
});

Once you've configured your environments:

  • $ ghjk envs cook $name to reify and install an environment.
  • $ ghjk envs activate $name to activate/switch to an environment.
  • And most usefully, $ ghjk sync $name to cook and then activate an environment.
    • Make sure to sync or cook your envs after changes.
  • If no $name is provided, most of these commands will operate on the default or currently active environment.

More details can be found in the user manual.

Development

Use the following command to enter a shell where the ghjk CLI is based on the code that's in the working tree. This will setup a separate installation at .dev.

$ deno task dev bash/fish/zsh

Run the tests in the repository through the deno task:

$ deno task test
# this supports filtering
$ deno task test --filter envHooks