Skip to content

Commit f389740

Browse files
authored
Prod 336/nested path dep (#102)
* Add support for nested and/or duplicated path dependencies * Add 'warn' logging function * Add error message for missing 'name' or 'version' key when parsing config file
1 parent f5b1be8 commit f389740

8 files changed

+430
-203
lines changed

src/dependencies.stanza

+346-142
Large diffs are not rendered by default.

src/dependency.stanza

+27-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public defmulti name (d: Dependency) -> String
1616
public defmulti path (d: Dependency) -> String
1717
public defmulti version-string? (d: Dependency) -> Maybe<String>:
1818
None()
19+
public defmulti dependency-type-name (d:Dependency) -> String
20+
1921
doc: \<DOC>
2022
Indicates whether a dependency should be parsed recursively.
2123

@@ -26,26 +28,42 @@ dependencies with.
2628
Other deps, like the `TaskDependency` does not have an `slm.toml`
2729
and is primarily for executing a command/process for external
2830
initialization.
29-
30-
This flag is for differentiating between these two types of
31-
dependency.
3231
<DOC>
33-
public defmulti recursive (d:Dependency) -> True|False :
32+
public deftype RecursiveDependency <: Dependency
33+
public defmulti recursive (d:Dependency) -> True|False
34+
defmethod recursive (d:Dependency) -> True|False :
35+
false
36+
defmethod recursive (d:RecursiveDependency) -> True|False :
3437
true
3538

3639
doc: \<DOC>
3740
Tool for filtering dependencies for recursives only.
3841
<DOC>
39-
public defn recursive-deps-only (deps:Seqable<Dependency>) -> Seqable<Dependency> :
40-
for dep in deps filter:
41-
recursive(dep)
42+
public defn recursive-deps-only (deps:Seqable<Dependency>) -> Seqable<RecursiveDependency> :
43+
filter-by<RecursiveDependency>(deps)
4244

4345
public defstruct UnknownDependencyTypeError <: Exception :
4446
dep:Dependency
4547

4648
public defmethod print (o:OutputStream, e:UnknownDependencyTypeError):
47-
val msg = "Unknown and Unhandled Dependency Type: %_" % [dep(e)]
48-
print(o, msg)
49+
print(o, "Unexpected dependency type: %_" % [object-type(dep(e))])
4950

51+
;============================================================
52+
;===================== Terminal Colors ======================
53+
;============================================================
5054

55+
public defn colored-name? (name:String) -> ColoredString :
56+
ColoredString(name)
57+
$> bold $> foreground{_, TerminalBrightWhite}
58+
$> clear-color?
59+
public defn colored-name? (d:Dependency) -> ColoredString :
60+
colored-name?(name(d))
5161

62+
public defn colored-version? (version:String) -> ColoredString :
63+
ColoredString(version)
64+
$> bold $> foreground{_, TerminalBrightGreen}
65+
$> clear-color?
66+
public defn colored-version? (v:SemanticVersion) -> ColoredString :
67+
colored-version?(to-string(v))
68+
public defn colored-version? (d:Dependency) -> ColoredString :
69+
colored-version?(value-or(version-string?(d), ""))

src/git-dep.stanza

+4-11
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ defpackage slm/git-dep:
1414
import slm/libgit-utils
1515

1616
; Dependencies specified by Git locator/version (e.g. `foo = "myorg/myuser|1.0.0"`)
17-
public defstruct GitDependency <: Dependency:
17+
public defstruct GitDependency <: RecursiveDependency:
1818
name: String with: (as-method => true)
1919
locator: String
2020
version: SemanticVersion
@@ -26,22 +26,15 @@ defmethod path (d: GitDependency):
2626
defmethod version-string? (d: GitDependency) -> One<String>:
2727
One(version-string(d))
2828

29+
defmethod dependency-type-name (d:GitDependency) -> String :
30+
"git"
31+
2932
defmethod print (o:OutputStream, d:GitDependency) :
3033
print(o, "%_ = { git = \"%_\", version = \"%_\" }" % [name(d), locator(d), version-string(d)])
3134

3235
public defn version-string (d: GitDependency) -> String:
3336
to-string(version(d))
3437

35-
public defn colored-version? (d: GitDependency) -> ColoredString:
36-
ColoredString(version-string(d))
37-
$> bold $> foreground{_, TerminalBrightGreen}
38-
$> clear-color?
39-
40-
public defn colored-name? (d: Dependency) -> ColoredString:
41-
ColoredString(name(d))
42-
$> bold $> foreground{_, TerminalBrightWhite}
43-
$> clear-color?
44-
4538
doc: \<DOC>
4639
Legacy Version of the Git Dependency Parser
4740

src/logging.stanza

+12-8
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ public defn program-name () -> String:
1111
val program-path = command-line-arguments()[0]
1212
program-path $> base-name? $> value-or{_, program-path}
1313

14-
defn colored-program-prefix () -> ColoredString:
15-
val prefix = to-string("%_:" % [program-name()])
16-
ColoredString(prefix, ColorSpec() $> bold $> foreground{_, TerminalBrightWhite})
17-
1814
defn program-prefix () -> ColoredString|String:
15+
val prefix = to-string("%_:" % [program-name()])
1916
if supports-color?():
20-
colored-program-prefix()
17+
ColoredString(prefix, ColorSpec() $> bold $> foreground{_, TerminalBrightWhite})
2118
else:
22-
to-string("%_:" % [program-name()])
19+
prefix
2320

2421
defn sub-command () -> String|Printable :
2522
val args = command-line-arguments()
@@ -45,8 +42,16 @@ public defn info (msg: Printable|String) -> False:
4542
println(current-output-stream(), "%_ %_" % [program-prefix(), msg])
4643
flush(current-output-stream() as FileOutputStream)
4744

45+
public defn warn (msg: Printable|String) -> False:
46+
println("%_ %_%_" % [
47+
program-prefix(),
48+
ColoredString("warning: ")
49+
$> bold $> dim $> foreground{_, TerminalYellow}
50+
$> clear-color?,
51+
msg,
52+
])
53+
4854
public defn error (msg: Printable|String -- code:Int = 1) -> Void:
49-
val program = program-name()
5055
println(current-error-stream(), "%_ %_ %_" % [
5156
program-prefix(),
5257
ColoredString("error:")
@@ -55,4 +60,3 @@ public defn error (msg: Printable|String -- code:Int = 1) -> Void:
5560
msg,
5661
])
5762
exit(code)
58-

src/path-dep.stanza

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defpackage slm/path-dep:
22
import core
3+
import core/parsed-path
34

45
import semver
56
import maybe-utils
@@ -10,7 +11,7 @@ defpackage slm/path-dep:
1011

1112

1213
; Dependencies specified by path (e.g. `foo = { path = "../foo" }`)
13-
public defstruct PathDependency <: Dependency:
14+
public defstruct PathDependency <: RecursiveDependency:
1415
name: String with: (as-method => true)
1516
path: String with: (as-method => true)
1617
version?: Maybe<SemanticVersion> with: ( default => None() )
@@ -23,18 +24,27 @@ defmethod version-string? (d:PathDependency) -> Maybe<String>:
2324
public defn version-string! (d:PathDependency) -> String:
2425
to-string $ value-or(version?(d), "UNSPECIFIED")
2526

27+
defmethod dependency-type-name (d:PathDependency) -> String :
28+
"path"
29+
2630
defmethod print (o:OutputStream, d:PathDependency) :
2731
print(o, "%_ = { path = \"%_\"" % [name(d), path(d)])
2832
match(version?(d)):
2933
(x:None): print(o, " }")
3034
(x:One<SemanticVersion>): print(o, ", version = \"%_\" }" % [to-string $ value(x)])
3135

3236

33-
public defn parse-path-dependency (name: String, path: String, version?:Maybe<String>, env-sub-enable:True|False) -> PathDependency:
34-
val path* = un-norm-path $ if env-sub-enable:
35-
env-var-substitute(path)
36-
else:
37-
path
37+
public defn parse-path-dependency (name:String, path:String,
38+
version?:Maybe<String>,
39+
toml-dir:String, env-sub-enable:True|False)
40+
-> PathDependency:
41+
val path* = let :
42+
val sub-path = env-var-substitute(path) when env-sub-enable else path
43+
val parsed-path = parse-path(sub-path)
44+
;If the path is relative, prepend the toml file path to it
45+
val anchored-path = parsed-path when absolute?(parsed-path) else
46+
relative-to-dir(parse-path(toml-dir), parsed-path)
47+
un-norm-path(to-string(anchored-path))
3848

3949
val version = match(version?):
4050
(x:None): x

src/pkg-dep.stanza

+5-19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ defpackage slm/pkg-dep:
33
import collections
44

55
import libarchive
6+
import semver
67
import maybe-utils
78
import term-colors
89
import toml
@@ -26,7 +27,7 @@ This dependency is intended to define a pre-compiled archive
2627
of stanza pkg binaries which can be linked into an slm project.
2728
This archive may be stored on a remote conan/artifactory server.
2829
<DOC>
29-
public defstruct PkgDependency <: Dependency & Hashable & Equalable:
30+
public defstruct PkgDependency <: RecursiveDependency & Hashable & Equalable:
3031
name:String with: (
3132
as-method => true
3233
ensure => ensure-not-empty!
@@ -37,16 +38,15 @@ public defstruct PkgDependency <: Dependency & Hashable & Equalable:
3738
with:
3839
hashable => true
3940

40-
defmethod recursive (d:PkgDependency) -> True|False :
41-
; a pkg can have recursive deps
42-
true
43-
4441
defmethod path (d:PkgDependency) -> String:
4542
path-join(SLM_DEPS_DIR, name(d))
4643

4744
defmethod equal? (a:PkgDependency, b:PkgDependency) -> True|False :
4845
name(a) == name(b) and version(a) == version(b) and type(a) == type(b) and to-string(options(a)) == to-string(options(b))
4946

47+
defmethod dependency-type-name (d:PkgDependency) -> String :
48+
"package"
49+
5050
public defn PkgDependency (
5151
name: String
5252
version: String ; may not always be a SemanticVersion
@@ -71,16 +71,6 @@ defmethod print (o:OutputStream, d:PkgDependency) :
7171
public defn version-string (d: PkgDependency) -> String:
7272
to-string(version(d))
7373

74-
public defn colored-version? (d: PkgDependency) -> ColoredString:
75-
ColoredString(version-string(d))
76-
$> bold $> foreground{_, TerminalBrightGreen}
77-
$> clear-color?
78-
79-
public defn colored-name? (d: PkgDependency) -> ColoredString:
80-
ColoredString(name(d))
81-
$> bold $> foreground{_, TerminalBrightWhite}
82-
$> clear-color?
83-
8474
defn options-to-string (d:PkgDependency) -> String :
8575
val elems = for kvp in options(d) seq:
8676
to-string("%~ = %~" % [key(kvp), value(kvp)])
@@ -116,10 +106,6 @@ public defn parse-pkg-dependency (name:String, table:TomlTable -- env-sub-enable
116106
value(x)
117107
PkgDependency(name, version, type, options)
118108

119-
public defn fetch-or-sync-pkgver (d: PkgDependency, parent-name:String|False = false, dep-path:String|False = false) -> Maybe<PkgDependency>:
120-
fetch-dependency-pkgver(d)
121-
to-maybe(d)
122-
123109
public defn fetch-dependency-pkgver (d: PkgDependency) -> False:
124110
info("fetching %_ at %_" % [colored-name?(d), colored-version?(d)])
125111
info("fetching with options: \"%_\"" % [entries(options(d))])

src/task.stanza

+3-3
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,6 @@ public defstruct TaskDependency <: Dependency & Hashable & Equalable:
163163
with:
164164
constructor => #TaskDependency
165165

166-
defmethod recursive (d:TaskDependency) -> True|False :
167-
false
168-
169166
defmethod path (d:TaskDependency) -> String:
170167
path-join(SLM_DEPS_DIR, name(d))
171168

@@ -180,6 +177,9 @@ defmethod hash (x:TaskDependency) -> Int :
180177
hash(k) + hash(v)
181178
hash(name(x)) + hash(task?(x)) + ptask-hash
182179

180+
defmethod dependency-type-name (d:TaskDependency) -> String :
181+
"task"
182+
183183
public defn TaskDependency (
184184
name:String,
185185
--

src/toml.stanza

+17-5
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,24 @@ This will replace strings like `{HOME}` with environment variable
7070
values if they exist.
7171
<DOC>
7272
public defn parse-slm-toml-file (file:String -- env-sub-enable:True|False = true) -> SlmToml:
73+
val [dir, _] = split-filepath(file)
7374
val table = file $> parse-file $> table
7475

75-
val name = table["name"] as String
76+
defn get-str-or-err (key:String) -> String :
77+
match(get?(table, key)) :
78+
(x:One<TomlValue>) :
79+
match(value(x)) :
80+
(s:String) : s
81+
(x) :
82+
error("%_ is invalid: value of '%_' key is not a string" % [file,
83+
key])
84+
(_) :
85+
error("%_ is invalid: '%_' key not found" % [file, key])
86+
87+
val name = get-str-or-err("name")
7688
debug("parse-slm-toml: name: \"%_\"" % [name])
7789

78-
val version = table["version"] as String
90+
val version = get-str-or-err("version")
7991
debug("parse-slm-toml: version: \"%_\"" % [version])
8092

8193
val compiler? = get-str?(table, "compiler")
@@ -94,7 +106,7 @@ public defn parse-slm-toml-file (file:String -- env-sub-enable:True|False = true
94106
parse-git-dependency(name, legacy)
95107
(table:TomlTable):
96108
debug("parse-slm-toml: calling parse-dependency(\"%_\", %_, %_)" % [name, table, env-sub-enable])
97-
parse-dependency(name, table, env-sub-enable)
109+
parse-dependency(name, table, dir, env-sub-enable)
98110

99111
SlmToml(name, version, compiler?, stanza-version?, dependencies)
100112

@@ -105,7 +117,7 @@ public defstruct InvalidDependencyConfigError <: Exception :
105117
defmethod print (o:OutputStream, e:InvalidDependencyConfigError) :
106118
print(o, "Invalid Dependency[%_]: %_" % [name(e), msg(e)])
107119

108-
defn parse-dependency (name:String, table:TomlTable, env-sub-enable:True|False) -> Dependency :
120+
defn parse-dependency (name:String, table:TomlTable, toml-dir:String, env-sub-enable:True|False) -> Dependency :
109121
val gitAttr = get-str?(table, "git")
110122
val pathAttr = get-str?(table, "path")
111123
val pkgAttr = get-str?(table, "pkg")
@@ -121,7 +133,7 @@ defn parse-dependency (name:String, table:TomlTable, env-sub-enable:True|False)
121133
match(pathAttr, gitAttr, pkgAttr, taskAttr):
122134
(p:One<String>, g:None, k: None, t:None): ; Path Dependency
123135
debug("parse-dependency: calling parse-path-dependency(\"%_\", ...)" % [name])
124-
parse-path-dependency(name, value(p), version, env-sub-enable)
136+
parse-path-dependency(name, value(p), version, toml-dir, env-sub-enable)
125137
(p:None, g:One<String>, k: None, t:None): ; Git Dependency
126138
debug("parse-dependency: calling parse-git-dependency(\"%_\", ...)" % [name])
127139
parse-git-dependency(name, value(g), version)

0 commit comments

Comments
 (0)