diff options
author | Vincent Ambo <mail@tazj.in> | 2021-12-15T16·31+0300 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2021-12-17T20·48+0000 |
commit | 564ad52b306bc1a3abe2afa9380bb0552144b23e (patch) | |
tree | 6f80c1c32a58b6240cc86bd89f0c9fcc879f3cbe | |
parent | 887ac4d3d479b2c5c991ed718792bba7a38b4948 (diff) |
feat(tools/magrathea): bootstrap a tool for working with depot r/3286
this is going to be a serious version of //tools/depot-build. right now it doesn't support parsing any target specs yet, so only shells and builds for the physical project of the current folder work. Change-Id: I4308e29da940571622ff9e539fbb8ededd27aca7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/4335 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in> Reviewed-by: grfn <grfn@gws.fyi>
-rwxr-xr-x | bin/__dispatch.sh | 3 | ||||
l--------- | bin/mg | 1 | ||||
-rw-r--r-- | tools/magrathea/default.nix | 23 | ||||
-rw-r--r-- | tools/magrathea/mg.scm | 110 |
4 files changed, 137 insertions, 0 deletions
diff --git a/bin/__dispatch.sh b/bin/__dispatch.sh index 0a049c1ecb20..c4d8b5991987 100755 --- a/bin/__dispatch.sh +++ b/bin/__dispatch.sh @@ -37,6 +37,9 @@ case "${TARGET_TOOL}" in meson) attr="third_party.nixpkgs.meson" ;; + mg) + attr="tools.magrathea" + ;; ninja) attr="third_party.nixpkgs.ninja" ;; diff --git a/bin/mg b/bin/mg new file mode 120000 index 000000000000..8390ec9c9652 --- /dev/null +++ b/bin/mg @@ -0,0 +1 @@ +__dispatch.sh \ No newline at end of file diff --git a/tools/magrathea/default.nix b/tools/magrathea/default.nix new file mode 100644 index 000000000000..fa0a5d89a172 --- /dev/null +++ b/tools/magrathea/default.nix @@ -0,0 +1,23 @@ +# magrathea helps you build planets +# +# it is a tool for working with monorepos in the style of tvl's depot +{ pkgs, ... }: + +pkgs.stdenv.mkDerivation { + name = "magrathea"; + src = ./.; + dontInstall = true; + + nativeBuildInputs = [ pkgs.chicken ]; + buildInputs = with pkgs.chickenPackages.chickenEggs; [ + matchable + srfi-13 + ]; + + propagatedBuildInputs = [ pkgs.git ]; + + buildPhase = '' + mkdir -p $out/bin + csc -o $out/bin/mg -static ${./mg.scm} + ''; +} diff --git a/tools/magrathea/mg.scm b/tools/magrathea/mg.scm new file mode 100644 index 000000000000..90798f156728 --- /dev/null +++ b/tools/magrathea/mg.scm @@ -0,0 +1,110 @@ +;; magrathea helps you build planets +;; +;; it is a tiny tool designed to ease workflows in monorepos that are +;; modeled after the tvl depot. +;; +;; users familiar with workflows from other, larger monorepos may be +;; used to having a build tool that can work in any tree location. +;; magrathea enables this, but with nix-y monorepos. + +(import (chicken base) + (chicken io) + (chicken irregex) + (chicken process) + (chicken process-context) + (chicken string) + (matchable)) + +(define usage #<<USAGE +usage: mg <command> [<target>] + +target: + a target specification with meaning inside of the repository. can + be absolute (starting with //) or relative to the current directory + (as long as said directory is inside of the repo). if no target is + specified, the current directory's physical target is built. + + for example: + + //tools/magrathea - absolute physical target + //foo/bar:baz - absolute virtual target + magrathea - relative physical target + :baz - relative virtual target + +commands: + build - build a target + shell - enter a shell with the target's build dependencies + +file all feedback on b.tvl.fyi +USAGE +) + +;; return the current repository root as a string +(define mg--repository-root #f) +(define (repository-root) + (or mg--repository-root + (begin + (set! mg--repository-root + (string-chomp + (call-with-input-pipe "git rev-parse --show-toplevel" + (lambda (p) (read-string #f p))))) + mg--repository-root))) + +;; determine the current path relative to the root of the repository +;; and return it as a list of path components. +(define (relative-repo-path) + (string-split + (substring (current-directory) (string-length (repository-root))) "/")) + +;; escape a string for interpolation in nix code +(define (nix-escape str) + (string-translate* str '(("\"" . "\\\"") + ("${" . "\\${")))) + +;; create a nix expression to build the attribute at the specified +;; components +;; +;; this uses builtins.getAttr explicitly to avoid problems with +;; escaping. +(define nix-expr-for + (lambda (parts #!optional (acc (conc "(import " (repository-root) " {})"))) + (match parts + [() (conc "with builtins; " acc)] + [_ (nix-expr-for (cdr parts) + (conc "(getAttr \"" (nix-escape (car parts)) "\" " acc ")"))]))) + +(define (execute-build components) + (let ((attr (string-intersperse components ".")) + (expr (nix-expr-for components))) + (print "[mg] building attribute '" attr "'") + (process-execute "nix-build" (list "-E" expr "--show-trace")))) + +(define (build args) + (match args + ;; simplest case: plain mg build with no target spec -> build + ;; the current folder's main target. + [() (execute-build (relative-repo-path))] + [other (print "not yet implemented")])) + +(define (execute-shell components) + (let ((attr (string-intersperse components ".")) + (expr (nix-expr-for components)) + (user-shell (or (get-environment-variable "SHELL") "bash"))) + (print "[mg] entering shell for '" attr "'") + (process-execute "nix-shell" + (list "-E" expr "--command" user-shell)))) + +(define (shell args) + (match args + [() (execute-shell (relative-repo-path))] + [other (print "not yet implemented")])) + +(define (main args) + (match args + [() (print usage)] + [("build" ...) (build (cdr args))] + [("shell" ...) (shell (cdr args))] + [other (begin (print "unknown command: mg " args) + (print usage))])) + +(main (command-line-arguments)) |