diff options
author | Ben Sima <ben@bsima.me> | 2019-11-02 15:33:13 -0700 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2019-11-02 15:33:13 -0700 |
commit | 9d114cfc773171b0a95bd4d2c39f1bb0eb783c8d (patch) | |
tree | 20766a760ed0141cf39153565e8552f6739c632d /Com/Simatime/bild.scm | |
parent | d2a37f5de160160eadbacd7b8dc2567f78a0543d (diff) |
rename everything back to caps to appease ghc
Diffstat (limited to 'Com/Simatime/bild.scm')
-rwxr-xr-x | Com/Simatime/bild.scm | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/Com/Simatime/bild.scm b/Com/Simatime/bild.scm new file mode 100755 index 0000000..6ac09ce --- /dev/null +++ b/Com/Simatime/bild.scm @@ -0,0 +1,159 @@ +;; +;; bild - a simple build tool +;; +;;; Notice: +;; +;; This is under active development. For now this is just a convenience wrapper +;; around `nix build`. The below commentary describes how this tool *should* +;; work. +;; +;;; Commentary: +;; +;; Design constraints +;; +;; - only input is a namespace, no subcommands, no packages +;; - no need to write specific build rules +;; - one rule for hs, one for rs, one for scm, and so on +;; - no need to distinguish between exe and lib, just have a single output +;; - never concerned with deployment/packaging - leave that to another tool (scp? tar?)) +;; +;; Features +;; +;; - namespace maps to filesystem +;; - no need for `bild -l` for listing available targets. Use `ls` or `tree` +;; - you build namespaces, not files/modules/packages/etc +;; - namespace maps to language modules +;; - build settings can be set in the file comments +;; - pwd is always considered the the source directory, no `src` vs `doc` etc. +;; - build methods automaticatly detected with file extensions +;; - flags modify the way to interact with the build +;; - -s = jump into a shell and/or repl +;; - -p = turn on profiling +;; - -t = limit build by type +;; - -e = exclude some regex in the ns tree +;; - -o = optimize level +;; +;; Example Commands +;; +;; bild [-rpt] <target..> +;; +;; The general scheme is to build the things described by the targets. A target +;; is a namespace. You can list as many as you want, but you must list at least +;; one. It could just be `.` for the current directory. Build outputs will go +;; into the _bild directory in the root of the project. +;; +;; bild biz.web +;; +;; Or `bild biz/web`. This shows building a file at ./biz/web.hs, this will +;; translate to something like `ghc --make Biz.Web`. +;; +;; bild -r <target> +;; +;; Starts a repl/shell for target. +;; - if target.hs, load ghci +;; - if target.scm, load scheme repl +;; - if target.clj, load a clojure repl +;; - if target.nix, load nix-shell +;; - and so on. +;; +;; bild -p <target> +;; +;; build target with profiling (if available) +;; +;; bild -t nix target +;; +;; only build target.nix, not target.hs and so on (in the case of multiple +;; targets with the same name but different extension). +;; +;; Here is an example integration with GHC. Given the following command-line +;; invocation to compile the namespace 'com.simatime.bild' which depends on +;; 'com.simatime.lib': +;; +;; ghc com/simatime/bild.hs -i com/simatime/lib.hs -o _bild/bild -v \ +;; -main-is Com.Simatime.Bild.main +;; +;; The general template of which is: +;; +;; ghc <source> -i <deps..> -o <target> -main-is <target>.main +;; +;; Some definitions: +;; +;; - <source> is some source file +;; - <deps..> is the stack of dependencies +;; - <target> is the target namespace, indicated by 'bild <target>' +;; +;; To fill out the build template, we can parse the file for known +;; namespaces. The general recipe is: +;; +;; 1. Create a list of namespaces in my git repo. This can be cached, or I can +;; integrate with git somehow. +;; 2. Read the <source> file corresponding to <target> +;; 3. Look for 'import <namespace>', where <namespace> is a namespace in the +;; aforementioned cache. +;; 4. If found, then save current build as a continuation and compile +;; <namespace>. Result gets put on the dependency stack +;; 5. When finished, return to building <target> +;; +;; Once the build command template is filled out, we can create the nix expression. +;; +;; Questions +;; +;; - how to import (third-party) dependencies? +;; 1 just don't have them...? yeah right +;; 2 the target.nix could be the build description for target.hs +;; 3 just use a default.nix for the com.whatever +;; 4 have a deps.nix file +;; 5 list them in the file with other settings +;; - how to handle multiple output formats? +;; - e.g. that ghcjs and ghc take the same input files... +;; - say you have a .md file, you want to bild it to pdf, html, and more. What do? +;; - i guess the nix file could return a set of drvs instead of a single drv +;; +;; TODO +;; - stream output from 'nix build' subprocess +;; - get rid of guile notes during execution +;; - ns<->path macro +;; - support list (scheme namespace) in ns<->path fns +;; +;;; Code: + +(define-module (Com Simatime bild) + #:use-module ((ice-9 popen) #:prefix popen/) + #:use-module ((ice-9 format) #:select (format)) + #:use-module ((ice-9 rdelim) #:prefix rdelim/) + #:use-module ((Com Simatime shell) #:prefix sh/) + #:use-module ((Com Simatime string) #:prefix string/) + #:export (ns? + ns->path + path->ns + main)) + +(define-syntax fmt + (syntax-rules () + ((fmt s args ...) + (format #f s args ...)))) + +(define (main args) + (let* ((root (sh/exec "git rev-parse --show-toplevel")) + (target (cadr args)) + (path (ns->path target))) + (display (fmt ":: bild ~a...\r" target)) + (sh/exec (fmt "nix build -f ~a/default.nix ~a" + root target)) + (display (fmt ":: bilt ~a" target)))) + +(define ns? symbol?) + +(define (ns->path ns) + (let ((to-path (lambda (s) (string/replace s #\. #\/)))) + (cond + ((symbol? ns) (to-path (symbol->string ns))) + ((string? ns) (to-path ns)) + (else (error "ns should be a string or symbol"))))) + +(define (path->ns path) + (let ((to-ns (lambda (s) (string/replace s #\/ #\.)))) + (cond + ((symbol? path) (to-ns (symbol->string path))) + ((string? path) (to-ns path)) + (else (error "path should be a string or symbol"))))) |