feat: rev opt in git dep + fix path opt in require
This commit is contained in:
parent
2f7825e06b
commit
22ecda20c7
6 changed files with 46 additions and 33 deletions
|
|
@ -17,7 +17,7 @@ In Lake, dependency sources currently come into flavors:
|
|||
-/
|
||||
inductive Source where
|
||||
| path (dir : FilePath)
|
||||
| git (url rev : String)
|
||||
| git (url : String) (rev : Option String)
|
||||
deriving Inhabited, Repr
|
||||
|
||||
/-- A `Dependency` of a package. -/
|
||||
|
|
|
|||
|
|
@ -17,21 +17,26 @@ namespace Lake
|
|||
section
|
||||
open Git
|
||||
|
||||
/-- Update the Git package in `dir` if necessary. -/
|
||||
/-- Update the Git package in `dir` to `rev` if not already at it. -/
|
||||
def updateGitPkg (name : String)
|
||||
(dir : FilePath) (rev : String) : (LogT IO) PUnit := do
|
||||
if (← headRevision dir) == rev then return
|
||||
logInfo s!"{name}: updating {dir} to revision {rev}"
|
||||
unless ← revisionExists rev dir do fetch dir
|
||||
checkoutDetach rev dir
|
||||
(dir : FilePath) (rev? : Option String) : LogT IO PUnit := do
|
||||
if let some rev := rev? then
|
||||
if (← headRevision dir) == rev then return
|
||||
logInfo s!"{name}: updating {dir} to revision {rev}"
|
||||
unless ← revisionExists rev dir do fetch dir
|
||||
checkoutDetach rev dir
|
||||
else
|
||||
logInfo s!"{name}: updating {dir}"
|
||||
pull dir
|
||||
|
||||
/-- Clone the Git package as `dir`. -/
|
||||
def cloneGitPkg (name : String)
|
||||
(dir : FilePath) (url rev : String) : (LogT IO) PUnit := do
|
||||
def cloneGitPkg (name : String) (dir : FilePath)
|
||||
(url : String) (rev? : Option String) : LogT IO PUnit := do
|
||||
logInfo s!"{name}: cloning {url} to {dir}"
|
||||
clone url dir
|
||||
let hash ← parseOriginRevision rev dir
|
||||
checkoutDetach hash dir
|
||||
if let some rev := rev? then
|
||||
let hash ← parseOriginRevision rev dir
|
||||
checkoutDetach hash dir
|
||||
|
||||
abbrev ResolveM := StateT (NameMap PackageEntry) <| LogT IO
|
||||
|
||||
|
|
@ -42,39 +47,37 @@ Attempts to reproduce the `PackageEntry` in the manifest (if one exists) unless
|
|||
`shouldUpdate` is true. Otherwise, produces the package based on `url` and `rev`
|
||||
and saves the result to the manifest.
|
||||
-/
|
||||
def materializeGitPkg (name : String)
|
||||
(dir : FilePath) (url rev : String) (shouldUpdate := true) : ResolveM PUnit := do
|
||||
def materializeGitPkg (name : String) (dir : FilePath)
|
||||
(url : String) (rev? : Option String) (shouldUpdate := true) : ResolveM PUnit := do
|
||||
if let some entry := (← get).find? name then
|
||||
if (← dir.isDir) then
|
||||
if url = entry.url then
|
||||
if shouldUpdate then
|
||||
let rev ← parseOriginRevision rev dir
|
||||
updateGitPkg name dir rev
|
||||
updateGitPkg name dir rev?
|
||||
let rev ← headRevision dir
|
||||
modify (·.insert name {entry with rev})
|
||||
else
|
||||
updateGitPkg name dir entry.rev
|
||||
else if shouldUpdate then
|
||||
logInfo s!"{name}: URL changed, deleting {dir} and cloning again"
|
||||
IO.FS.removeDirAll dir
|
||||
cloneGitPkg name dir url rev
|
||||
let rev ← parseOriginRevision rev dir
|
||||
cloneGitPkg name dir url rev?
|
||||
let rev ← headRevision dir
|
||||
modify (·.insert name {entry with url, rev})
|
||||
else
|
||||
if shouldUpdate then
|
||||
cloneGitPkg name dir url rev
|
||||
let rev ← parseOriginRevision rev dir
|
||||
cloneGitPkg name dir url rev?
|
||||
let rev ← headRevision dir
|
||||
modify (·.insert name {entry with url, rev})
|
||||
else
|
||||
cloneGitPkg name dir entry.url entry.rev
|
||||
else
|
||||
if (← dir.isDir) then
|
||||
let rev ← parseOriginRevision rev dir
|
||||
let rev ← headRevision dir
|
||||
modify (·.insert name {name, url, rev})
|
||||
if (← headRevision dir) == rev then return
|
||||
updateGitPkg name dir rev
|
||||
else
|
||||
cloneGitPkg name dir url rev
|
||||
let rev ← parseOriginRevision rev dir
|
||||
cloneGitPkg name dir url rev?
|
||||
let rev ← headRevision dir
|
||||
modify (·.insert name {name, url, rev})
|
||||
|
||||
end
|
||||
|
|
@ -87,10 +90,10 @@ def materializeDep (ws : Workspace)
|
|||
(pkg : Package) (dep : Dependency) (shouldUpdate := true) : ResolveM FilePath :=
|
||||
match dep.src with
|
||||
| Source.path dir => return pkg.dir / dir
|
||||
| Source.git url rev => do
|
||||
| Source.git url rev? => do
|
||||
let name := dep.name.toString (escape := false)
|
||||
let depDir := ws.packagesDir / name
|
||||
materializeGitPkg name depDir url rev shouldUpdate
|
||||
materializeGitPkg name depDir url rev? shouldUpdate
|
||||
return depDir
|
||||
|
||||
/--
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ syntax fromPath :=
|
|||
term
|
||||
|
||||
syntax fromGit :=
|
||||
&" git " term:max "@" term:max ("/" term)?
|
||||
&" git " term:max ("@" term:max)? ("/" term)?
|
||||
|
||||
syntax fromClause :=
|
||||
fromGit <|> fromPath
|
||||
|
|
@ -23,10 +23,16 @@ syntax depSpec :=
|
|||
ident " from " fromClause (" with " term)?
|
||||
|
||||
def evalDepSpec : Syntax → TermElabM Dependency
|
||||
| `(depSpec| $name:ident from git $url @ $rev / $path $[with $args?:term]?) => do
|
||||
| `(depSpec| $name:ident from git $url $[@ $rev?]? $[/ $path?]? $[with $args?:term]?) => do
|
||||
let url ← evalTerm String url
|
||||
let rev ← evalTerm String rev
|
||||
let path ← evalTerm System.FilePath path
|
||||
let rev ←
|
||||
match rev? with
|
||||
| some rev => some <$> evalTerm String rev
|
||||
| none => pure none
|
||||
let path ←
|
||||
match path? with
|
||||
| some path => evalTerm System.FilePath path
|
||||
| none => pure "."
|
||||
let args ← match args? with
|
||||
| some args => evalTerm (List String) args
|
||||
| none => pure []
|
||||
|
|
@ -48,7 +54,8 @@ require bar from git "url.git"@"rev"/"optional"/"path-to"/"dir-with-pkg"
|
|||
```
|
||||
|
||||
Either form supports the optional `with` clause.
|
||||
The `/` and the following term in the git form of `require` is optional.
|
||||
The `@"rev"` and `/"path"/"dir"` parts of the git form of `require`
|
||||
are optional.
|
||||
|
||||
The elements of both the `from` and `with` clauses are proper terms so
|
||||
normal computation is supported within them (though parentheses made be
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ def quietInit (repo : Option FilePath := none) :=
|
|||
def fetch (repo : Option FilePath := none) :=
|
||||
execGit #["fetch"] repo
|
||||
|
||||
def pull (repo : Option FilePath := none) :=
|
||||
execGit #["pull"] repo
|
||||
|
||||
def checkoutBranch (branch : String) (repo : Option FilePath := none) :=
|
||||
execGit #["checkout", "-B", branch] repo
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ require foo from "path"/"to"/"local"/"package" with ["optional","args"]
|
|||
require bar from git "url.git"@"rev"/"optional"/"path-to"/"dir-with-pkg"
|
||||
```
|
||||
|
||||
The first form adds a local dependency and the second form adds a Git dependency. For a Git dependency, the revision can be a commit hash, branch, or tag. Also, the `/` and the following term of the `require` is optional.
|
||||
The first form adds a local dependency and the second form adds a Git dependency. For a Git dependency, the revision can be a commit hash, branch, or tag. Also, the `@"rev"` and `/"path-to"/"term"` parts of the `require` are optional.
|
||||
|
||||
Both forms also support an optional `with` clause to specify arguments to pass to the dependency's package configuration (i.e., same as `args` in a `lake build -- <args...>` invocation). The elements of both the `from` and `with` clauses are proper terms so normal computation is supported within them (though parentheses made be required to disambiguate the syntax).
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ open System Lake DSL
|
|||
package git_hello
|
||||
|
||||
require hello from
|
||||
git "../.."@"master"/"examples"/"hello"
|
||||
git "../.."/"examples"/"hello"
|
||||
|
||||
@[defaultTarget]
|
||||
lean_exe git_hello {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue