feat: rev opt in git dep + fix path opt in require

This commit is contained in:
tydeu 2022-06-10 19:28:52 -04:00
parent 2f7825e06b
commit 22ecda20c7
6 changed files with 46 additions and 33 deletions

View file

@ -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. -/

View file

@ -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
/--

View file

@ -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

View file

@ -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

View file

@ -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).

View file

@ -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 {