Support multiple named exports globally
Add multi-root bundle support across the toolchain: - `compile`: Accept multiple definition names via `-x NAME` (repeatable or comma-separated). Exports all requested definitions as named roots in a single bundle. Defaults to "main" when no names are given. - `export`: Accept comma-separated hashes in the positional argument and multiple `-n`/`names` flags. Exports all resolved roots in one bundle. - Server: Add `GET /bundle/roots?n=...&h=...` endpoint that resolves multiple stored-term names and/or raw Merkle hashes, returning a single bundle containing all of them as roots. - Wire: Export `defaultExportNames` helper for generating default export names when none are supplied. - Drop `cereal` dependency from `tricu.cabal` (no longer used).
This commit is contained in:
40
src/Main.hs
40
src/Main.hs
@@ -28,8 +28,8 @@ data TricuArgs
|
||||
= Repl
|
||||
| Evaluate { file :: [FilePath], form :: EvaluatedForm }
|
||||
| TDecode { file :: [FilePath] }
|
||||
| Compile { inputFile :: FilePath, outFile :: FilePath, exportNameOpt :: String }
|
||||
| Export { hash :: String, exportNameOpt :: String, outFile :: FilePath }
|
||||
| Compile { inputFile :: FilePath, outFile :: FilePath, names :: [String] }
|
||||
| Export { hash :: String, exportNameOpt :: String, outFile :: FilePath, names :: [String] }
|
||||
| Import { inFile :: FilePath }
|
||||
| Serve { host :: String, port :: Int }
|
||||
deriving (Show, Data, Typeable)
|
||||
@@ -67,11 +67,13 @@ decodeMode = TDecode
|
||||
|
||||
exportMode :: TricuArgs
|
||||
exportMode = Export
|
||||
{ hash = def &= help "Full/prefix hash or stored term name to export."
|
||||
{ hash = def &= help "Hash or stored term name(s) to export (comma-separated)."
|
||||
&= name "h" &= typ "HASH_OR_NAME"
|
||||
, exportNameOpt = def &= help "Export name to place in the bundle manifest. Defaults to the stored term name when exporting by name; otherwise defaults to root."
|
||||
, exportNameOpt = def &= help "Export name (legacy; use -n NAME for full control)."
|
||||
&= name "n" &= typ "NAME"
|
||||
, outFile = def &= help "Output file path for the bundle." &= name "o" &= typ "FILE"
|
||||
, names = def &= help "Export name(s) for the bundle manifest (comma-separated or repeated -n)."
|
||||
&= typ "NAME"
|
||||
}
|
||||
&= help "Export a Merkle bundle from the content store."
|
||||
&= explicit
|
||||
@@ -92,8 +94,8 @@ compileMode = Compile
|
||||
&= name "f" &= typ "FILE"
|
||||
, outFile = def &= help "Output bundle file path (.tri.bundle)."
|
||||
&= name "o" &= typ "FILE"
|
||||
, exportNameOpt = def &= help "Definition name to use as the bundle root. Defaults to 'main'."
|
||||
&= name "x" &= typ "NAME"
|
||||
, names = def &= help "Definition name(s) to export as bundle roots (comma-separated or repeated -x). Defaults to 'main'."
|
||||
&= name "x" &= typ "NAME"
|
||||
}
|
||||
&= help "Compile a tricu source file into a standalone Arborix portable bundle."
|
||||
&= explicit
|
||||
@@ -151,13 +153,23 @@ main = do
|
||||
[] -> getContents
|
||||
(filePath:_) -> readFile filePath
|
||||
putStrLn $ decodeResult $ result $ evalTricu Map.empty $ parseTricu value
|
||||
Export { hash = hashStr, exportNameOpt = exportNameArg, outFile = outFilePath } -> do
|
||||
Export { hash = hashStr, exportNameOpt = legacyName, names = namesArg, outFile = outFilePath } -> do
|
||||
conn <- initContentStore
|
||||
(resolvedHash, storedNames) <- resolveExportTarget conn hashStr
|
||||
expName <- chooseExportName exportNameArg hashStr storedNames
|
||||
bundleData <- exportNamedBundle conn [(expName, resolvedHash)]
|
||||
let hashList = T.split (== ',') (T.pack hashStr)
|
||||
hashes <- mapM (\h -> do
|
||||
(resolvedHash, _) <- resolveExportTarget conn (T.unpack h)
|
||||
return resolvedHash) hashList
|
||||
-- Merge legacy -n and new -n (names); names wins when non-empty
|
||||
let allNames = if null namesArg
|
||||
then if null legacyName then [] else [legacyName]
|
||||
else namesArg
|
||||
let expNames = if null allNames
|
||||
then defaultExportNames (length hashes)
|
||||
else map T.pack allNames
|
||||
let exports = zip expNames hashes
|
||||
bundleData <- exportNamedBundle conn exports
|
||||
BL.writeFile outFilePath (BL.fromStrict bundleData)
|
||||
putStrLn $ "Exported bundle export " ++ unpack expName ++ " -> " ++ unpack resolvedHash ++ " to " ++ outFilePath
|
||||
putStrLn $ "Exported bundle with " ++ show (length exports) ++ " export(s) to " ++ outFilePath
|
||||
close conn
|
||||
Import { inFile = importFile } -> do
|
||||
conn <- initContentStore
|
||||
@@ -166,9 +178,9 @@ main = do
|
||||
putStrLn $ "Imported " ++ show (length roots) ++ " root(s):"
|
||||
mapM_ (\r -> putStrLn $ " " ++ unpack r) roots
|
||||
close conn
|
||||
Compile { inputFile = compileInputFile, outFile = compileOutFile, exportNameOpt = exportNameArg } ->
|
||||
let bundleExportName = if null exportNameArg then Nothing else Just (T.pack exportNameArg)
|
||||
in compileFile compileInputFile compileOutFile bundleExportName
|
||||
Compile { inputFile = compileInputFile, outFile = compileOutFile, names = namesArg } ->
|
||||
let exportNames = if null namesArg then [] else map T.pack namesArg
|
||||
in compileFile compileInputFile compileOutFile exportNames
|
||||
Serve { host = hostStr, port = portNum } -> do
|
||||
putStrLn $ "Starting Arborix bundle server on " ++ hostStr ++ ":" ++ show portNum
|
||||
putStrLn $ " GET /bundle/hash/:hash -- primary endpoint"
|
||||
|
||||
Reference in New Issue
Block a user