feat: lake run <s> for s in any pkg
This commit is contained in:
parent
113caf73fa
commit
e96b338cd9
11 changed files with 62 additions and 27 deletions
|
|
@ -168,8 +168,8 @@ def helpScriptRun :=
|
|||
USAGE:
|
||||
lake script run [[<package>/]<script>] [<args>...]
|
||||
|
||||
This command runs the given `script` from `package`, passing `args` to it.
|
||||
Defaults to the root package.
|
||||
This command runs the `script` of the workspace (or the specific `package`),
|
||||
passing `args` to it.
|
||||
|
||||
A bare `lake run` command will run the default script(s) of the root package
|
||||
(with no arguments)."
|
||||
|
|
@ -180,7 +180,7 @@ def helpScriptDoc :=
|
|||
USAGE:
|
||||
lake script doc [<package>/]<script>
|
||||
|
||||
Print the docstring of `script` in `package`. Defaults to the root package."
|
||||
Print the docstring of `script` in the workspace or the specific `package`."
|
||||
|
||||
def helpServe :=
|
||||
"Start the Lean language server
|
||||
|
|
|
|||
|
|
@ -181,10 +181,17 @@ def verifyInstall (opts : LakeOptions) : ExceptT CliError MainM PUnit := do
|
|||
let (leanInstall, _) ← opts.getInstall
|
||||
verifyLeanVersion leanInstall
|
||||
|
||||
def parseScriptSpec (ws : Workspace) (spec : String) : Except CliError (Package × String) :=
|
||||
def parseScriptSpec (ws : Workspace) (spec : String) : Except CliError Script :=
|
||||
match spec.splitOn "/" with
|
||||
| [script] => return (ws.root, script)
|
||||
| [pkg, script] => return (← parsePackageSpec ws pkg, script)
|
||||
| [scriptName] =>
|
||||
match ws.findScript? scriptName with
|
||||
| some script => return script
|
||||
| none => throw <| CliError.unknownScript spec
|
||||
| [pkg, scriptName] => do
|
||||
let pkg ← parsePackageSpec ws pkg
|
||||
match pkg.scripts.find? scriptName with
|
||||
| some script => return script
|
||||
| none => throw <| CliError.unknownScript spec
|
||||
| _ => throw <| CliError.invalidScriptSpec spec
|
||||
|
||||
def parseTemplateSpec (spec : String) : Except CliError InitTemplate :=
|
||||
|
|
@ -220,11 +227,8 @@ protected nonrec def run : CliM PUnit := do
|
|||
let ws ← loadWorkspace config
|
||||
if let some spec ← takeArg? then
|
||||
let args ← takeArgs
|
||||
let (pkg, scriptName) ← parseScriptSpec ws spec
|
||||
if let some script := pkg.scripts.find? scriptName then
|
||||
exit <| ← script.run args |>.run {opaqueWs := ws}
|
||||
else do
|
||||
throw <| CliError.unknownScript scriptName
|
||||
let script ← parseScriptSpec ws spec
|
||||
exit <| ← script.run args |>.run {opaqueWs := ws}
|
||||
else
|
||||
for script in ws.root.defaultScripts do
|
||||
exitIfErrorCode <| ← script.run [] |>.run {opaqueWs := ws}
|
||||
|
|
@ -236,13 +240,10 @@ protected def doc : CliM PUnit := do
|
|||
let config ← mkLoadConfig (← getThe LakeOptions)
|
||||
noArgsRem do
|
||||
let ws ← loadWorkspace config
|
||||
let (pkg, scriptName) ← parseScriptSpec ws spec
|
||||
if let some script := pkg.scripts.find? scriptName then
|
||||
match script.doc? with
|
||||
| some doc => IO.println doc
|
||||
| none => throw <| CliError.missingScriptDoc scriptName
|
||||
else
|
||||
throw <| CliError.unknownScript scriptName
|
||||
let script ← parseScriptSpec ws spec
|
||||
match script.doc? with
|
||||
| some doc => IO.println doc
|
||||
| none => throw <| CliError.missingScriptDoc script.name
|
||||
|
||||
protected def help : CliM PUnit := do
|
||||
IO.println <| helpScript <| (← takeArg?).getD ""
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ A package `Script` is a `ScriptFn` definition that is
|
|||
indexed by a `String` key and can be be run by `lake run <key> [-- <args>]`.
|
||||
-/
|
||||
structure Script where
|
||||
/-- The full name of the `Script` (e.g., `pkg/script`). -/
|
||||
name : String
|
||||
fn : ScriptFn
|
||||
doc? : Option String
|
||||
deriving Inhabited
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ def addPackage (pkg : Package) (self : Workspace) : Workspace :=
|
|||
@[inline] def findPackage? (name : Name) (self : Workspace) : Option (NPackage name) :=
|
||||
self.packageMap.find? name
|
||||
|
||||
/-- Try to find a script in the workspace with the given name. -/
|
||||
def findScript? (script : Name) (self : Workspace) : Option Script :=
|
||||
self.packageArray.findSome? (·.scripts.find? script)
|
||||
|
||||
/-- Check if the module is local to any package in the workspace. -/
|
||||
def isLocalModule (mod : Name) (self : Workspace) : Bool :=
|
||||
self.packageMap.any fun _ pkg => pkg.isLocalModule mod
|
||||
|
|
|
|||
|
|
@ -63,12 +63,15 @@ Load the remainder of a `Package`
|
|||
from its configuration environment after resolving its dependencies.
|
||||
-/
|
||||
def Package.finalize (self : Package) (deps : Array Package) : LogIO Package := do
|
||||
let env := self.configEnv; let opts := self.leanOpts
|
||||
let env := self.configEnv
|
||||
let opts := self.leanOpts
|
||||
let strName := self.name.toString (escape := false)
|
||||
|
||||
-- Load Script, Facet, & Target Configurations
|
||||
let scripts : NameMap Script ← mkTagMap env scriptAttr fun name => do
|
||||
let fn ← IO.ofExcept <| evalConstCheck env opts ScriptFn ``ScriptFn name
|
||||
return {fn, doc? := (← findDocString? env name)}
|
||||
let scripts : NameMap Script ← mkTagMap env scriptAttr fun scriptName => do
|
||||
let name := strName ++ "/" ++ scriptName.toString (escape := false)
|
||||
let fn ← IO.ofExcept <| evalConstCheck env opts ScriptFn ``ScriptFn scriptName
|
||||
return {name, fn, doc? := ← findDocString? env scriptName}
|
||||
let defaultScripts ← defaultScriptAttr.getAllEntries env |>.mapM fun name =>
|
||||
if let some script := scripts.find? name then pure script else
|
||||
error s!"package is missing script `{name}` marked as a default"
|
||||
|
|
|
|||
2
src/lake/examples/scripts/.gitignore
vendored
2
src/lake/examples/scripts/.gitignore
vendored
|
|
@ -1 +1 @@
|
|||
/lakefile.olean
|
||||
lakefile.olean
|
||||
|
|
|
|||
9
src/lake/examples/scripts/dep/lakefile.lean
Normal file
9
src/lake/examples/scripts/dep/lakefile.lean
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import Lake
|
||||
open Lake DSL
|
||||
|
||||
package dep
|
||||
|
||||
@[default_script]
|
||||
script hello do
|
||||
IO.println "Hello from Dep!"
|
||||
return 0
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
dep/hello
|
||||
scripts/dismiss
|
||||
scripts/greet
|
||||
Hello, world!
|
||||
|
|
@ -5,12 +6,15 @@ Hello, me!
|
|||
Display a greeting
|
||||
|
||||
USAGE:
|
||||
lake run greet [name]
|
||||
lake run greet [name]
|
||||
|
||||
Greet the entity with the given name. Otherwise, greet the whole world.
|
||||
|
||||
Hello from Dep!
|
||||
Hello from Dep!
|
||||
error: unknown script nonexistant
|
||||
error: unknown script nonexistant
|
||||
dep/hello
|
||||
scripts/dismiss
|
||||
scripts/greet
|
||||
Hello, world!
|
||||
|
|
|
|||
4
src/lake/examples/scripts/lake-manifest.json
Normal file
4
src/lake/examples/scripts/lake-manifest.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{"version": 5,
|
||||
"packagesDir": "lake-packages",
|
||||
"packages":
|
||||
[{"path": {"opts": {}, "name": "dep", "inherited": false, "dir": ".\\dep"}}]}
|
||||
|
|
@ -2,6 +2,7 @@ import Lake
|
|||
open Lake DSL
|
||||
|
||||
package scripts
|
||||
require dep from "dep"
|
||||
|
||||
/--
|
||||
Display a greeting
|
||||
|
|
@ -19,7 +20,6 @@ script greet (args) do
|
|||
IO.println "Hello, world!"
|
||||
return 0
|
||||
|
||||
|
||||
@[default_script]
|
||||
script dismiss do
|
||||
IO.println "Goodbye!"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
|
||||
# make prefix `/` behave on MSYS2
|
||||
[ "$OSTYPE" == "msys" ] && export MSYS2_ARG_CONV_EXCL=*
|
||||
|
||||
./clean.sh
|
||||
LAKE=${LAKE:-../../build/bin/lake}
|
||||
|
||||
$LAKE update
|
||||
$LAKE script list | tee produced.out
|
||||
$LAKE run scripts/greet | tee -a produced.out
|
||||
$LAKE run /greet | tee -a produced.out
|
||||
$LAKE script run greet me | tee -a produced.out
|
||||
$LAKE script doc greet | tee -a produced.out
|
||||
$LAKE script run hello | tee -a produced.out
|
||||
$LAKE script run dep/hello | tee -a produced.out
|
||||
($LAKE script run nonexistant 2>&1 | tee -a produced.out) && false || true
|
||||
($LAKE script doc nonexistant 2>&1 | tee -a produced.out) && false || true
|
||||
$LAKE scripts | tee -a produced.out
|
||||
$LAKE run | tee -a produced.out
|
||||
|
||||
# TODO: Figure out why indent in USAGE disappears in the CI
|
||||
# FIXME: Figure out why indent in USAGE disappears in the CI
|
||||
diff --ignore-all-space --strip-trailing-cr expected.out produced.out
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue