summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2022-08-03 14:11:18 -0400
committerBen Sima <ben@bsima.me>2022-08-03 15:20:01 -0400
commit27a631b2c94df80ac5da8c97b66a3e99e1813811 (patch)
treef706daa9710b7412d23f1dea4288cd22318e0039
parent935d5dc1c8d4c60a70d79a3f47718f9dcf5684fd (diff)
Print bild JSON analysis as a dictionary instead of a stream
-rw-r--r--Biz/Bild.hs130
-rw-r--r--Biz/Bild.nix5
-rwxr-xr-xBiz/Ide/repl6
-rw-r--r--Biz/Namespace.hs5
4 files changed, 79 insertions, 67 deletions
diff --git a/Biz/Bild.hs b/Biz/Bild.hs
index 06c102f..2b7a2e1 100644
--- a/Biz/Bild.hs
+++ b/Biz/Bild.hs
@@ -51,6 +51,10 @@
--
-- * -o = optimize level
--
+-- * the build is planned out with an analysis, which can be viewed
+-- beforehand with `--json`. The analysis includes compiler flags, which
+-- can be used in `repl` for testing compilation locally.
+--
-- == Example Commands
--
-- > bild [opts] <target..>
@@ -58,7 +62,8 @@
-- 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 `:!bild %` in vim to build whatever you're working on,
--- or `bild **/*` to build everything.
+-- or `bild **/*` to build everything, or `fd .hs -X bild` to build all Haskell
+-- files.
--
-- Build outputs will go into the `_` directory in the root of the project.
--
@@ -136,8 +141,7 @@ main = Cli.main <| Cli.Plan help move test_ pure
root <- Env.getEnv "BIZ_ROOT"
let Just ns = Namespace.fromPath root "Biz/Bild.hs"
analyze mempty ns
- /> Map.elems
- +> traverse (build False False)
+ +> build False False
+> \case
[Exit.ExitFailure _] ->
Test.assertFailure "can't bild bild"
@@ -157,18 +161,17 @@ move args = do
/> catMaybes
+> foldM analyze mempty
/> Map.filter (namespace .> isBuildableNs)
- /> Map.elems
+> printOrBuild
+> exitSummary
where
- printOrBuild :: [Target] -> IO [ExitCode]
+ printOrBuild :: Analysis -> IO [ExitCode]
printOrBuild targets
| args `Cli.has` Cli.longOption "json" =
- Log.wipe >> traverse_ putJSON targets >> pure [Exit.ExitSuccess]
+ Log.wipe >> putJSON targets >> pure [Exit.ExitSuccess]
| otherwise = do
root <- Env.getEnv "BIZ_ROOT"
createHier root
- traverse (build isTest isLoud) targets
+ build isTest isLoud targets
isTest = args `Cli.has` Cli.longOption "test"
isLoud = args `Cli.has` Cli.longOption "loud"
putJSON = Aeson.encode .> ByteString.toStrict .> Char8.putStrLn
@@ -188,7 +191,7 @@ Usage:
Options:
--test Run tests on a target after building
--loud Show all output from compiler
- --json Only analyze and print as JSON, don't build
+ --json Print the build plan as JSON, don't build
-h, --help Print this info
|]
@@ -596,62 +599,63 @@ test loud Target {..} = case compiler of
>> Log.br
>> pure Exit.ExitSuccess
-build :: Bool -> Bool -> Target -> IO Exit.ExitCode
-build andTest loud target@Target {..} = do
+build :: Bool -> Bool -> Analysis -> IO [Exit.ExitCode]
+build andTest loud analysis = do
root <- Env.getEnv "BIZ_ROOT"
- case compiler of
- Gcc ->
- Log.info ["bild", label, "gcc", nschunk namespace]
- >> proc loud namespace "gcc" compilerFlags
- where
- label = case out of
- Bin _ -> "bin"
- _ -> "lib"
- GhcExe -> do
- Log.info ["bild", "dev", "ghc-exe", nschunk namespace]
- exitcode <- proc loud namespace "ghc" compilerFlags
- if andTest && isSuccess exitcode
- then test loud target
- else pure exitcode
- GhcLib -> do
- Log.info ["bild", "dev", "ghc-lib", nschunk namespace]
- proc
- loud
- namespace
- "ghc"
- compilerFlags
- Guile -> do
- Log.info ["bild", "dev", "guile", nschunk namespace]
- _ <- proc loud namespace "guild" compilerFlags
- when (out /= None) <| do
- writeFile
- (root </> outdir out)
- <| Text.pack
- <| joinWith
- "\n"
- [ "#!/usr/bin/env bash",
- "guile -C \""
- <> root </> intdir
- <> "\" -e main "
- <> "-s "
- <> Namespace.toPath namespace
- <> " \"$@\""
- ]
- p <- Dir.getPermissions <| root </> outdir out
- Dir.setPermissions (root </> outdir out) (Dir.setOwnerExecutable True p)
- pure Exit.ExitSuccess
- NixBuild -> do
- Log.info ["bild", "nix", builder, nschunk namespace]
- proc loud namespace "nix-build" compilerFlags
- Copy -> do
- Log.warn ["bild", "copy", "TODO", nschunk namespace]
- pure Exit.ExitSuccess
- Rustc -> do
- Log.info ["bild", "dev", "rust", nschunk namespace]
- proc loud namespace "rustc" compilerFlags
- Sbcl -> do
- Log.info ["bild", "dev", "lisp", nschunk namespace]
- proc loud namespace "sbcl" compilerFlags
+ forM (Map.elems analysis) <| \target@Target {..} -> do
+ case compiler of
+ Gcc ->
+ Log.info ["bild", label, "gcc", nschunk namespace]
+ >> proc loud namespace "gcc" compilerFlags
+ where
+ label = case out of
+ Bin _ -> "bin"
+ _ -> "lib"
+ GhcExe -> do
+ Log.info ["bild", "dev", "ghc-exe", nschunk namespace]
+ exitcode <- proc loud namespace "ghc" compilerFlags
+ if andTest && isSuccess exitcode
+ then test loud target
+ else pure exitcode
+ GhcLib -> do
+ Log.info ["bild", "dev", "ghc-lib", nschunk namespace]
+ proc
+ loud
+ namespace
+ "ghc"
+ compilerFlags
+ Guile -> do
+ Log.info ["bild", "dev", "guile", nschunk namespace]
+ _ <- proc loud namespace "guild" compilerFlags
+ when (out /= None) <| do
+ writeFile
+ (root </> outdir out)
+ <| Text.pack
+ <| joinWith
+ "\n"
+ [ "#!/usr/bin/env bash",
+ "guile -C \""
+ <> root </> intdir
+ <> "\" -e main "
+ <> "-s "
+ <> Namespace.toPath namespace
+ <> " \"$@\""
+ ]
+ p <- Dir.getPermissions <| root </> outdir out
+ Dir.setPermissions (root </> outdir out) (Dir.setOwnerExecutable True p)
+ pure Exit.ExitSuccess
+ NixBuild -> do
+ Log.info ["bild", "nix", builder, nschunk namespace]
+ proc loud namespace "nix-build" compilerFlags
+ Copy -> do
+ Log.warn ["bild", "copy", "TODO", nschunk namespace]
+ pure Exit.ExitSuccess
+ Rustc -> do
+ Log.info ["bild", "dev", "rust", nschunk namespace]
+ proc loud namespace "rustc" compilerFlags
+ Sbcl -> do
+ Log.info ["bild", "dev", "lisp", nschunk namespace]
+ proc loud namespace "sbcl" compilerFlags
data Proc = Proc
{ loud :: Bool,
diff --git a/Biz/Bild.nix b/Biz/Bild.nix
index ab120db..b6946c9 100644
--- a/Biz/Bild.nix
+++ b/Biz/Bild.nix
@@ -98,7 +98,10 @@ rec {
# gather data needed for compiling by analyzing the main module
analyze = main:
- # builtins.head
+ let
+ path = lib.strings.removePrefix (builtins.getEnv "BIZ_ROOT" + "/") (toString main);
+ in
+ lib.attrsets.getAttrFromPath [path]
(lib.trivial.importJSON
(runBildAnalyze main + "/analysis.json"));
diff --git a/Biz/Ide/repl b/Biz/Ide/repl
index a8fc124..8f92fba 100755
--- a/Biz/Ide/repl
+++ b/Biz/Ide/repl
@@ -26,9 +26,9 @@ fi
fi
targets=${@:?}
json=$(bild --json ${targets[@]})
- langdeps=$(jq --raw-output '.langdeps | join(" ")' <<< $json)
- sysdeps=$(jq --raw-output '.sysdeps | join(" ")' <<< $json)
- exts=$(jq --raw-output '.namespace.ext' <<< $json | sort | uniq)
+ langdeps=$(jq --raw-output '.[].langdeps | join(" ")' <<< $json)
+ sysdeps=$(jq --raw-output '.[].sysdeps | join(" ")' <<< $json)
+ exts=$(jq --raw-output '.[].namespace.ext' <<< $json | sort | uniq)
BILD="(import $BIZ_ROOT/Biz/Bild.nix {})"
for lib in ${sysdeps[@]}; do
flags+=(--packages "$BILD.private.nixpkgs.${lib}")
diff --git a/Biz/Namespace.hs b/Biz/Namespace.hs
index cdc4464..72e3fa1 100644
--- a/Biz/Namespace.hs
+++ b/Biz/Namespace.hs
@@ -19,9 +19,11 @@ where
import Alpha
import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.Types as Aeson
import qualified Data.Char as Char
import qualified Data.List as List
import qualified Data.List.Split as List
+import qualified Data.Text as Text
import qualified Text.Regex.Applicative as Regex
data Ext
@@ -43,6 +45,9 @@ data Ext
data Namespace = Namespace {path :: [String], ext :: Ext}
deriving (Eq, Show, Generic, Aeson.ToJSON, Ord)
+instance Aeson.ToJSONKey Namespace where
+ toJSONKey = Aeson.toJSONKeyText (Text.pack <. toPath)
+
fromPath :: String -> String -> Maybe Namespace
fromPath bizRoot absPath =
List.stripPrefix bizRoot absPath