Atlas: now in its own repository (#22066)

* Atlas: now in its own repository

* progress
This commit is contained in:
Andreas Rumpf
2023-06-10 17:32:11 +02:00
committed by GitHub
parent 8bba04078c
commit 21d941c16a
33 changed files with 15 additions and 3010 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
--define:ssl

View File

@@ -1,246 +0,0 @@
#
# Atlas Package Cloner
# (c) Copyright 2021 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
##[
Syntax taken from strscans.nim:
================= ========================================================
``$$`` Matches a single dollar sign.
``$*`` Matches until the token following the ``$*`` was found.
The match is allowed to be of 0 length.
``$+`` Matches until the token following the ``$+`` was found.
The match must consist of at least one char.
``$s`` Skips optional whitespace.
================= ========================================================
]##
import tables
from strutils import continuesWith, Whitespace
type
Opcode = enum
MatchVerbatim # needs verbatim match
Capture0Until
Capture1Until
Capture0UntilEnd
Capture1UntilEnd
SkipWhitespace
Instr = object
opc: Opcode
arg1: uint8
arg2: uint16
Pattern* = object
code: seq[Instr]
usedMatches: int
error: string
# A rewrite rule looks like:
#
# foo$*bar -> https://gitlab.cross.de/$1
proc compile*(pattern: string; strings: var seq[string]): Pattern =
proc parseSuffix(s: string; start: int): int =
result = start
while result < s.len and s[result] != '$':
inc result
result = Pattern(code: @[], usedMatches: 0, error: "")
var p = 0
while p < pattern.len:
if pattern[p] == '$' and p+1 < pattern.len:
case pattern[p+1]
of '$':
if result.code.len > 0 and result.code[^1].opc in {
MatchVerbatim, Capture0Until, Capture1Until, Capture0UntilEnd, Capture1UntilEnd}:
# merge with previous opcode
let key = strings[result.code[^1].arg2] & "$"
var idx = find(strings, key)
if idx < 0:
idx = strings.len
strings.add key
result.code[^1].arg2 = uint16(idx)
else:
var idx = find(strings, "$")
if idx < 0:
idx = strings.len
strings.add "$"
result.code.add Instr(opc: MatchVerbatim,
arg1: uint8(0), arg2: uint16(idx))
inc p, 2
of '+', '*':
let isPlus = pattern[p+1] == '+'
let pEnd = parseSuffix(pattern, p+2)
let suffix = pattern.substr(p+2, pEnd-1)
p = pEnd
if suffix.len == 0:
result.code.add Instr(opc: if isPlus: Capture1UntilEnd else: Capture0UntilEnd,
arg1: uint8(result.usedMatches), arg2: uint16(0))
else:
var idx = find(strings, suffix)
if idx < 0:
idx = strings.len
strings.add suffix
result.code.add Instr(opc: if isPlus: Capture1Until else: Capture0Until,
arg1: uint8(result.usedMatches), arg2: uint16(idx))
inc result.usedMatches
of 's':
result.code.add Instr(opc: SkipWhitespace)
inc p, 2
else:
result.error = "unknown syntax '$" & pattern[p+1] & "'"
break
elif pattern[p] == '$':
result.error = "unescaped '$'"
break
else:
let pEnd = parseSuffix(pattern, p)
let suffix = pattern.substr(p, pEnd-1)
var idx = find(strings, suffix)
if idx < 0:
idx = strings.len
strings.add suffix
result.code.add Instr(opc: MatchVerbatim,
arg1: uint8(0), arg2: uint16(idx))
p = pEnd
type
MatchObj = object
m: int
a: array[20, (int, int)]
proc matches(s: Pattern; strings: seq[string]; input: string): MatchObj =
template failed =
result.m = -1
return result
var i = 0
for instr in s.code:
case instr.opc
of MatchVerbatim:
if continuesWith(input, strings[instr.arg2], i):
inc i, strings[instr.arg2].len
else:
failed()
of Capture0Until, Capture1Until:
block searchLoop:
let start = i
while i < input.len:
if continuesWith(input, strings[instr.arg2], i):
if instr.opc == Capture1Until and i == start:
failed()
result.a[result.m] = (start, i-1)
inc result.m
inc i, strings[instr.arg2].len
break searchLoop
inc i
failed()
of Capture0UntilEnd, Capture1UntilEnd:
if instr.opc == Capture1UntilEnd and i >= input.len:
failed()
result.a[result.m] = (i, input.len-1)
inc result.m
i = input.len
of SkipWhitespace:
while i < input.len and input[i] in Whitespace: inc i
if i < input.len:
# still unmatched stuff was left:
failed()
proc translate(m: MatchObj; outputPattern, input: string): string =
result = newStringOfCap(outputPattern.len)
var i = 0
var patternCount = 0
while i < outputPattern.len:
if i+1 < outputPattern.len and outputPattern[i] == '$':
if outputPattern[i+1] == '#':
inc i, 2
if patternCount < m.a.len:
let (a, b) = m.a[patternCount]
for j in a..b: result.add input[j]
inc patternCount
elif outputPattern[i+1] in {'1'..'9'}:
var n = ord(outputPattern[i+1]) - ord('0')
inc i, 2
while i < outputPattern.len and outputPattern[i] in {'0'..'9'}:
n = n * 10 + (ord(outputPattern[i]) - ord('0'))
inc i
patternCount = n
if n-1 < m.a.len:
let (a, b) = m.a[n-1]
for j in a..b: result.add input[j]
else:
# just ignore the wrong pattern:
inc i
else:
result.add outputPattern[i]
inc i
proc replace*(s: Pattern; outputPattern, input: string): string =
var strings: seq[string] = @[]
let m = s.matches(strings, input)
if m.m < 0:
result = ""
else:
result = translate(m, outputPattern, input)
type
Patterns* = object
s: seq[(Pattern, string)]
t: Table[string, string]
strings: seq[string]
proc initPatterns*(): Patterns =
Patterns(s: @[], t: initTable[string, string](), strings: @[])
proc addPattern*(p: var Patterns; inputPattern, outputPattern: string): string =
if '$' notin inputPattern and '$' notin outputPattern:
p.t[inputPattern] = outputPattern
result = ""
else:
let code = compile(inputPattern, p.strings)
if code.error.len > 0:
result = code.error
else:
p.s.add (code, outputPattern)
result = ""
proc substitute*(p: Patterns; input: string): string =
result = p.t.getOrDefault(input)
if result.len == 0:
for i in 0..<p.s.len:
let m = p.s[i][0].matches(p.strings, input)
if m.m >= 0:
return translate(m, p.s[i][1], input)
proc replacePattern*(inputPattern, outputPattern, input: string): string =
var strings: seq[string] = @[]
let code = compile(inputPattern, strings)
result = replace(code, outputPattern, input)
when isMainModule:
# foo$*bar -> https://gitlab.cross.de/$1
const realInput = "$fooXXbar$z00end"
var strings: seq[string] = @[]
let code = compile("$$foo$*bar$$$*z00$*", strings)
echo code
let m = code.matches(strings, realInput)
echo m.m
echo translate(m, "$1--$#-$#-", realInput)
echo translate(m, "https://gitlab.cross.de/$1", realInput)

View File

@@ -1,51 +0,0 @@
## OS utilities like 'withDir'.
## (c) 2021 Andreas Rumpf
import os, strutils, osproc
proc isUrl*(x: string): bool =
x.startsWith("git://") or x.startsWith("https://") or x.startsWith("http://")
proc cloneUrl*(url, dest: string; cloneUsingHttps: bool): string =
## Returns an error message on error or else "".
result = ""
var modUrl =
if url.startsWith("git://") and cloneUsingHttps:
"https://" & url[6 .. ^1]
else: url
# github + https + trailing url slash causes a
# checkout/ls-remote to fail with Repository not found
var isGithub = false
if modUrl.contains("github.com") and modUrl.endsWith("/"):
modUrl = modUrl[0 .. ^2]
isGithub = true
let (_, exitCode) = execCmdEx("git ls-remote --quiet --tags " & modUrl)
var xcode = exitCode
if isGithub and exitCode != QuitSuccess:
# retry multiple times to avoid annoying github timeouts:
for i in 0..4:
os.sleep(4000)
xcode = execCmdEx("git ls-remote --quiet --tags " & modUrl)[1]
if xcode == QuitSuccess: break
if xcode == QuitSuccess:
# retry multiple times to avoid annoying github timeouts:
let cmd = "git clone --recursive " & modUrl & " " & dest
for i in 0..4:
if execShellCmd(cmd) == 0: return ""
os.sleep(4000)
result = "exernal program failed: " & cmd
elif not isGithub:
let (_, exitCode) = execCmdEx("hg identify " & modUrl)
if exitCode == QuitSuccess:
let cmd = "hg clone " & modUrl & " " & dest
for i in 0..4:
if execShellCmd(cmd) == 0: return ""
os.sleep(4000)
result = "exernal program failed: " & cmd
else:
result = "Unable to identify url: " & modUrl
else:
result = "Unable to identify url: " & modUrl

View File

@@ -1,161 +0,0 @@
import std / [json, os, sets, strutils, httpclient, uri]
type
Package* = ref object
# Required fields in a package.
name*: string
url*: string # Download location.
license*: string
downloadMethod*: string
description*: string
tags*: seq[string] # \
# From here on, optional fields set to the empty string if not available.
version*: string
dvcsTag*: string
web*: string # Info url for humans.
proc optionalField(obj: JsonNode, name: string, default = ""): string =
if hasKey(obj, name) and obj[name].kind == JString:
result = obj[name].str
else:
result = default
proc requiredField(obj: JsonNode, name: string): string =
result = optionalField(obj, name, "")
proc fromJson*(obj: JSonNode): Package =
result = Package()
result.name = obj.requiredField("name")
if result.name.len == 0: return nil
result.version = obj.optionalField("version")
result.url = obj.requiredField("url")
if result.url.len == 0: return nil
result.downloadMethod = obj.requiredField("method")
if result.downloadMethod.len == 0: return nil
result.dvcsTag = obj.optionalField("dvcs-tag")
result.license = obj.optionalField("license")
result.tags = @[]
for t in obj["tags"]:
result.tags.add(t.str)
result.description = obj.requiredField("description")
result.web = obj.optionalField("web")
const PackagesDir* = "packages"
proc getPackages*(workspaceDir: string): seq[Package] =
result = @[]
var uniqueNames = initHashSet[string]()
var jsonFiles = 0
for kind, path in walkDir(workspaceDir / PackagesDir):
if kind == pcFile and path.endsWith(".json"):
inc jsonFiles
let packages = json.parseFile(path)
for p in packages:
let pkg = p.fromJson()
if pkg != nil and not uniqueNames.containsOrIncl(pkg.name):
result.add(pkg)
proc `$`*(pkg: Package): string =
result = pkg.name & ":\n"
result &= " url: " & pkg.url & " (" & pkg.downloadMethod & ")\n"
result &= " tags: " & pkg.tags.join(", ") & "\n"
result &= " description: " & pkg.description & "\n"
result &= " license: " & pkg.license & "\n"
if pkg.web.len > 0:
result &= " website: " & pkg.web & "\n"
proc toTags(j: JsonNode): seq[string] =
result = @[]
if j.kind == JArray:
for elem in items j:
result.add elem.getStr("")
proc singleGithubSearch(term: string): JsonNode =
# For example:
# https://api.github.com/search/repositories?q=weave+language:nim
var client = newHttpClient()
try:
let x = client.getContent("https://api.github.com/search/repositories?q=" & encodeUrl(term) & "+language:nim")
result = parseJson(x)
except:
result = parseJson("{\"items\": []}")
finally:
client.close()
proc githubSearch(seen: var HashSet[string]; terms: seq[string]) =
for term in terms:
let results = singleGithubSearch(term)
for j in items(results.getOrDefault("items")):
let p = Package(
name: j.getOrDefault("name").getStr,
url: j.getOrDefault("html_url").getStr,
downloadMethod: "git",
tags: toTags(j.getOrDefault("topics")),
description: j.getOrDefault("description").getStr,
license: j.getOrDefault("license").getOrDefault("spdx_id").getStr,
web: j.getOrDefault("html_url").getStr
)
if not seen.containsOrIncl(p.url):
echo p
proc getUrlFromGithub*(term: string): string =
let results = singleGithubSearch(term)
var matches = 0
result = ""
for j in items(results.getOrDefault("items")):
if cmpIgnoreCase(j.getOrDefault("name").getStr, term) == 0:
if matches == 0:
result = j.getOrDefault("html_url").getStr
inc matches
if matches != 1:
# ambiguous, not ok!
result = ""
proc search*(pkgList: seq[Package]; terms: seq[string]) =
var seen = initHashSet[string]()
template onFound =
echo pkg
seen.incl pkg.url
break forPackage
for pkg in pkgList:
if terms.len > 0:
block forPackage:
for term in terms:
let word = term.toLower
# Search by name.
if word in pkg.name.toLower:
onFound()
# Search by tag.
for tag in pkg.tags:
if word in tag.toLower:
onFound()
else:
echo(pkg)
githubSearch seen, terms
if seen.len == 0 and terms.len > 0:
echo("No package found.")
type PkgCandidates* = array[3, seq[Package]]
proc determineCandidates*(pkgList: seq[Package];
terms: seq[string]): PkgCandidates =
result[0] = @[]
result[1] = @[]
result[2] = @[]
for pkg in pkgList:
block termLoop:
for term in terms:
let word = term.toLower
if word == pkg.name.toLower:
result[0].add pkg
break termLoop
elif word in pkg.name.toLower:
result[1].add pkg
break termLoop
else:
for tag in pkg.tags:
if word in tag.toLower:
result[2].add pkg
break termLoop

View File

@@ -1,313 +0,0 @@
## SAT solver
## (c) 2021 Andreas Rumpf
## Based on explanations and Haskell code from
## https://andrew.gibiansky.com/blog/verification/writing-a-sat-solver/
## Formulars as packed ASTs, no pointers no cry. Solves formulars with many
## thousands of variables in no time.
type
FormKind* = enum
FalseForm, TrueForm, VarForm, NotForm, AndForm, OrForm, ExactlyOneOfForm # roughly 8 so the last 3 bits
BaseType = int32
Atom = distinct BaseType
VarId* = distinct BaseType
Formular* = seq[Atom] # linear storage
proc `==`*(a, b: VarId): bool {.borrow.}
const
KindBits = 3
KindMask = 0b111
template kind(a: Atom): FormKind = FormKind(BaseType(a) and KindMask)
template intVal(a: Atom): BaseType = BaseType(a) shr KindBits
proc newVar*(val: VarId): Atom {.inline.} =
Atom((BaseType(val) shl KindBits) or BaseType(VarForm))
proc newOperation(k: FormKind; val: BaseType): Atom {.inline.} =
Atom((val shl KindBits) or BaseType(k))
proc trueLit(): Atom {.inline.} = Atom(TrueForm)
proc falseLit(): Atom {.inline.} = Atom(FalseForm)
proc lit(k: FormKind): Atom {.inline.} = Atom(k)
when false:
proc isTrueLit(a: Atom): bool {.inline.} = a.kind == TrueForm
proc isFalseLit(a: Atom): bool {.inline.} = a.kind == FalseForm
proc varId(a: Atom): VarId =
assert a.kind == VarForm
result = VarId(BaseType(a) shr KindBits)
type
PatchPos = distinct int
FormPos = distinct int
proc prepare(dest: var Formular; source: Formular; sourcePos: FormPos): PatchPos =
result = PatchPos dest.len
dest.add source[sourcePos.int]
proc patch(f: var Formular; pos: PatchPos) =
let pos = pos.int
let k = f[pos].kind
assert k > VarForm
let distance = int32(f.len - pos)
f[pos] = newOperation(k, distance)
proc nextChild(f: Formular; pos: var int) {.inline.} =
let x = f[int pos]
pos += (if x.kind <= VarForm: 1 else: int(intVal(x)))
iterator sonsReadonly(f: Formular; n: FormPos): FormPos =
var pos = n.int
assert f[pos].kind > VarForm
let last = pos + f[pos].intVal
inc pos
while pos < last:
yield FormPos pos
nextChild f, pos
iterator sons(dest: var Formular; source: Formular; n: FormPos): FormPos =
let patchPos = prepare(dest, source, n)
for x in sonsReadonly(source, n): yield x
patch dest, patchPos
# String representation
proc toString(dest: var string; f: Formular; n: FormPos) =
assert n.int >= 0
assert n.int < f.len
case f[n.int].kind
of FalseForm: dest.add 'F'
of TrueForm: dest.add 'T'
of VarForm:
dest.add 'v'
dest.addInt varId(f[n.int]).int
else:
case f[n.int].kind
of AndForm:
dest.add "(&"
of OrForm:
dest.add "(|"
of ExactlyOneOfForm:
dest.add "(1=="
of NotForm:
dest.add "(~"
else: assert false, "cannot happen"
for child in sonsReadonly(f, n):
toString(dest, f, child)
dest.add ' '
dest[^1] = ')'
proc `$`*(f: Formular): string =
assert f.len > 0
toString(result, f, FormPos 0)
type
Builder* = object
f: Formular
toPatch: seq[PatchPos]
proc isEmpty*(b: Builder): bool {.inline.} =
b.f.len == 0 or b.f.len == 1 and b.f[0].kind in {NotForm, AndForm, OrForm, ExactlyOneOfForm}
proc openOpr*(b: var Builder; k: FormKind) =
b.toPatch.add PatchPos b.f.len
b.f.add newOperation(k, 0)
proc add*(b: var Builder; a: Atom) =
b.f.add a
proc closeOpr*(b: var Builder) =
patch(b.f, b.toPatch.pop())
proc toForm*(b: var Builder): Formular =
assert b.toPatch.len == 0, "missing `closeOpr` calls"
result = move b.f
# Code from the blog translated into Nim and into our representation
const
NoVar = VarId(-1)
proc freeVariable(f: Formular): VarId =
## returns NoVar if there is no free variable.
for i in 0..<f.len:
if f[i].kind == VarForm: return varId(f[i])
return NoVar
type
BindingKind* = enum
dontCare,
setToFalse,
setToTrue
Solution* = seq[BindingKind]
proc simplify(dest: var Formular; source: Formular; n: FormPos; sol: Solution): FormKind =
## Returns either a Const constructor or a simplified expression;
## if the result is not a Const constructor, it guarantees that there
## are no Const constructors in the source tree further down.
let s = source[n.int]
result = s.kind
case result
of FalseForm, TrueForm:
# nothing interesting to do:
dest.add s
of VarForm:
let v = varId(s).int
if v < sol.len:
case sol[v]
of dontCare:
dest.add s
of setToFalse:
dest.add falseLit()
result = FalseForm
of setToTrue:
dest.add trueLit()
result = TrueForm
else:
dest.add s
of NotForm:
let oldLen = dest.len
var inner: FormKind
for child in sons(dest, source, n):
inner = simplify(dest, source, child, sol)
if inner in {FalseForm, TrueForm}:
setLen dest, oldLen
result = (if inner == FalseForm: TrueForm else: FalseForm)
dest.add lit(result)
of AndForm, OrForm:
let (tForm, fForm) = if result == AndForm: (TrueForm, FalseForm)
else: (FalseForm, TrueForm)
let initialLen = dest.len
var childCount = 0
for child in sons(dest, source, n):
let oldLen = dest.len
let inner = simplify(dest, source, child, sol)
# ignore 'and T' or 'or F' subexpressions:
if inner == tForm:
setLen dest, oldLen
elif inner == fForm:
# 'and F' is always false and 'or T' is always true:
result = fForm
break
else:
inc childCount
if result == fForm:
setLen dest, initialLen
dest.add lit(result)
elif childCount == 1:
for i in initialLen..<dest.len-1:
dest[i] = dest[i+1]
setLen dest, dest.len-1
result = dest[initialLen].kind
elif childCount == 0:
# that means all subexpressions where ignored:
setLen dest, initialLen
result = tForm
dest.add lit(result)
of ExactlyOneOfForm:
let initialLen = dest.len
var childCount = 0
var couldEval = 0
for child in sons(dest, source, n):
let oldLen = dest.len
let inner = simplify(dest, source, child, sol)
# ignore 'exactlyOneOf F' subexpressions:
if inner == FalseForm:
setLen dest, oldLen
else:
if inner == TrueForm:
inc couldEval
inc childCount
if couldEval == childCount:
setLen dest, initialLen
if couldEval != 1:
dest.add lit FalseForm
else:
dest.add lit TrueForm
elif childCount == 1:
for i in initialLen..<dest.len-1:
dest[i] = dest[i+1]
setLen dest, dest.len-1
result = dest[initialLen].kind
proc satisfiable*(f: Formular; s: var Solution): bool =
let v = freeVariable(f)
if v == NoVar:
result = f[0].kind == TrueForm
else:
result = false
# We have a variable to guess.
# Construct the two guesses.
# Return whether either one of them works.
if v.int >= s.len: s.setLen v.int+1
# try `setToFalse` first so that we don't end up with unnecessary dependencies:
s[v.int] = setToFalse
var falseGuess: Formular
let res = simplify(falseGuess, f, FormPos 0, s)
if res == TrueForm:
result = true
else:
result = satisfiable(falseGuess, s)
if not result:
s[v.int] = setToTrue
var trueGuess: Formular
let res = simplify(trueGuess, f, FormPos 0, s)
if res == TrueForm:
result = true
else:
result = satisfiable(trueGuess, s)
if not result:
# heuristic that provides a solution that comes closest to the "real" conflict:
s[v.int] = if trueGuess.len <= falseGuess.len: setToFalse else: setToTrue
when isMainModule:
proc main =
var b: Builder
b.openOpr(AndForm)
b.openOpr(OrForm)
b.add newVar(VarId 1)
b.add newVar(VarId 2)
b.add newVar(VarId 3)
b.add newVar(VarId 4)
b.closeOpr
b.openOpr(ExactlyOneOfForm)
b.add newVar(VarId 5)
b.add newVar(VarId 6)
b.add newVar(VarId 7)
#b.openOpr(NotForm)
b.add newVar(VarId 8)
#b.closeOpr
b.closeOpr
b.add newVar(VarId 5)
b.add newVar(VarId 6)
b.closeOpr
let f = toForm(b)
echo "original: "
echo f
var s: Solution
echo satisfiable(f, s)
echo "solution"
for i in 0..<s.len:
echo "v", i, " ", s[i]
main()

View File

@@ -1,63 +0,0 @@
type
PerDirData = object
dirname: string
cmd: Command
exitCode: int
output: string
template toData(a, b, c, d): untyped =
PerDirData(dirname: a, cmd: b, exitCode: c, output: d)
const
TestLog = [
toData("balls", GitPull, 0, "Already up to date.\n"),
toData("grok", GitDiff, 0, ""),
toData("grok", GitTags, 0, "2ca193c31fa2377c1e991a080d60ca3215ff6cf0 refs/tags/0.0.1\n48007554b21ba2f65c726ae2fdda88d621865b4a refs/tags/0.0.2\n7092a0286421c7818cd335cca9ebc72d03d866c2 refs/tags/0.0.3\n62707b8ac684efac35d301dbde57dc750880268e refs/tags/0.0.4\n876f2504e0c2f785ffd2cf65a78e2aea474fa8aa refs/tags/0.0.5\nb7eb1f2501aa2382cb3a38353664a13af62a9888 refs/tags/0.0.6\nf5d818bfd6038884b3d8b531c58484ded20a58a4 refs/tags/0.1.0\n961eaddea49c3144d130d105195583d3f11fb6c6 refs/tags/0.2.0\n15ab8ed8d4f896232a976a9008548bd53af72a66 refs/tags/0.2.1\n426a7d7d4603f77ced658e73ad7f3f582413f6cd refs/tags/0.3.0\n83cf7a39b2fe897786fb0fe01a7a5933c3add286 refs/tags/0.3.1\n8d2e3c900edbc95fa0c036fd76f8e4f814aef2c1 refs/tags/0.3.2\n48b43372f49a3bb4dc0969d82a0fca183fb94662 refs/tags/0.3.3\n9ca947a3009ea6ba17814b20eb953272064eb2e6 refs/tags/0.4.0\n1b5643d04fba6d996a16d1ffc13d034a40003f8f refs/tags/0.5.0\n486b0eb580b1c465453d264ac758cc490c19c33e refs/tags/0.5.1\naedb0d9497390e20b9d2541cef2bb05a5cda7a71 refs/tags/0.5.2\n"),
toData("grok", GitCurrentCommit, 0, "349c15fd1e03f1fcdd81a1edefba3fa6116ab911\n"),
toData("grok", GitMergeBase, 0, "349c15fd1e03f1fcdd81a1edefba3fa6116ab911\n1b5643d04fba6d996a16d1ffc13d034a40003f8f\n349c15fd1e03f1fcdd81a1edefba3fa6116ab911\n"),
toData("grok", GitCheckout, 0, "1b5643d04fba6d996a16d1ffc13d034a40003f8f"), # watch out!
toData("ups", GitDiff, 0, ""),
toData("ups", GitTags, 0, "4008f9339cd22b30e180bc87a6cca7270fd28ac1 refs/tags/0.0.2\n19bc490c22b4f5b0628c31cdedead1375b279356 refs/tags/0.0.3\nff34602aaea824cb46d6588cd5fe1178132e9702 refs/tags/0.0.4\n09de599138f20b745133b6e4fe563e204415a7e8 refs/tags/0.0.5\n85fee3b74798311108a105635df31f892150f5d0 refs/tags/0.0.6\nfd303913b22b121dc42f332109e9c44950b9acd4 refs/tags/0.0.7\n"),
toData("ups", GitCurrentCommit, 0, "74c31af8030112dac758440aa51ef175992f71f3\n"),
toData("ups", GitMergeBase, 0, "74c31af8030112dac758440aa51ef175992f71f3\n4008f9339cd22b30e180bc87a6cca7270fd28ac1\n74c31af8030112dac758440aa51ef175992f71f3\n"),
toData("ups", GitCheckout, 0, "4008f9339cd22b30e180bc87a6cca7270fd28ac1"),
toData("sync", GitDiff, 0, ""),
toData("sync", GitRevParse, 0, "810bd2d75e9f6e182534ae2488670b51a9f13fc3\n"),
toData("sync", GitCurrentCommit, 0, "de5c7337ebc22422190e8aeca37d05651735f440\n"),
toData("sync", GitMergeBase, 0, "de5c7337ebc22422190e8aeca37d05651735f440\n810bd2d75e9f6e182534ae2488670b51a9f13fc3\n810bd2d75e9f6e182534ae2488670b51a9f13fc3\n"),
toData("npeg", GitDiff, 0, ""),
toData("npeg", GitTags, 0, "8df2f0c9391995fd086b8aab00e8ab7aded1e8f0 refs/tags/0.1.0\n4c959a72db5283b55eeef491076eefb5e02316f1 refs/tags/0.10.0\n802f47c0f7f4318a4f0858ba5a6a6ed2333bde71 refs/tags/0.11.0\n82c8d92837108dce225358ace2c416bf9a3f30ce refs/tags/0.12.0\n87d2f2c4f6ef7da350d45beb5a336611bde7f518 refs/tags/0.13.0\n39964f0d220bfaade47a568bf03c1cf28aa2bc37 refs/tags/0.14.0\nbe9f03f92304cbeab70572944a8563db9b23b2fb refs/tags/0.14.1\na933fb9832566fc95273e417597bfb4faf564ca6 refs/tags/0.15.0\n6aad2e438c52ff0636c7bfb64338e444ac3e83ba refs/tags/0.16.0\nf4ddffb5848c42c6151743dd9c7eddcaaabc56cc refs/tags/0.17.0\n30b446b39442cdbc53a97018ab8a54149aa7c3b7 refs/tags/0.17.1\n1a9d36aa3b34a6169d4530463f1c17a3fe1e075e refs/tags/0.18.0\ndd34f903a9a63b876cb2db19b7a4ce0bcc252134 refs/tags/0.19.0\nd93d49c81fc8722d7929ac463b435c0f2e10c53b refs/tags/0.2.0\neeae7746c9b1118bcf27744ab2aee26969051256 refs/tags/0.20.0\n8c3471a548129f3bf62df15cd0fd8cca1787d852 refs/tags/0.21.0\nc0e873a17bc713c80e74fec3c30cb62dcd5d194a refs/tags/0.21.1\nbae84c47a1bb259b209b6f6be1582327b784539d refs/tags/0.21.2\nbfcb4bcae76a917c3c88736ca773e4cb67dbb2d8 refs/tags/0.21.3\n0eabb7c462d30932049f0b7e6a030c1562cf9fee refs/tags/0.22.0\n2e75367095f54d4351005078bad98041a55b14c1 refs/tags/0.22.1\n814ea235dd398108d7b18f966694c3d951575701 refs/tags/0.22.2\na812064587d983c129737f8500bf74990e6b8dab refs/tags/0.23.0\nbd969ad3745db0d66022564cac76cf9424651104 refs/tags/0.23.1\na037c646a47623b92718efadc2bb74d03664b360 refs/tags/0.23.2\n078475ccceeaca0fac947492acdd24514da8d863 refs/tags/0.24.0\ne7bd87dc992512fd5825a557a56907647e03c979 refs/tags/0.24.1\n45ea601e1c7f64fb857bc99df984b86673621d2c refs/tags/0.3.0\n1ea9868a3fee3aa487ab7ec9129208a4dd483d0d refs/tags/0.4.0\n39afdb5733d3245386d29d08c5ff61c89268f499 refs/tags/0.5.0\n458c7b5910fcb157af3fc51bc3b3e663fdb3ed4a refs/tags/0.6.0\n06c38bd8563d822455bc237c2a98c153d938ed1b refs/tags/0.7.0\nf446b6056eef6d8dc9d8b47a79aca93d17dc8230 refs/tags/0.8.0\nbb25a195133f9f7af06386d0809793923cc5e8ab refs/tags/0.9.0\n"),
toData("npeg", GitCurrentCommit, 0, "5d80f93aa720898936668b3bc47d0fff101ec414\n"),
toData("npeg", GitMergeBase, 0, "5d80f93aa720898936668b3bc47d0fff101ec414\na037c646a47623b92718efadc2bb74d03664b360\na037c646a47623b92718efadc2bb74d03664b360\n"),
toData("testes", GitDiff, 0, ""),
toData("testes", GitTags, 0, "3ce9b2968b5f644755a0ced1baa3eece88c2f12e refs/tags/0.1.0\nf73af8318b54737678fab8b54bdcd8a451015e0d refs/tags/0.1.1\nd21d84d37b161a123a43318bae353108755916de refs/tags/0.1.2\n5c36b6095353ed03b08ac939d00aff2d73f79a35 refs/tags/0.1.3\na1220d11237ee8f135f772ff9731c11b2d91ba31 refs/tags/0.1.4\n574f741b90d04a7ce8c9b990e6077708d7ad076e refs/tags/0.1.5\nced0a9e58234b680def6931578e09165a32e6291 refs/tags/0.1.6\nbb248952e8742a6011eb1a45a9d2059aeb0341d7 refs/tags/0.1.7\nabb7d7c552da0a8e0ddc586c15ccf7e74b0d068b refs/tags/0.10.0\n6e42a768a90d6442196b344bcdcb6f834b76e7b7 refs/tags/0.2.0\n9d136c3a0851ca2c021f5fb4f7b63f0a0ef77232 refs/tags/0.2.1\ndcb282b2da863fd2939e1969cec7a99788feb456 refs/tags/0.2.2\nf708a632afaa40a322a1a61c1c13722edac8e8c5 refs/tags/0.3.0\n3213f59e3f9ba052452c59f01d1418360d856af6 refs/tags/0.3.1\nf7bb1743dffd327958dfcebae4cfb6f61cc1cb8c refs/tags/0.3.2\n6b64569ebecad6bc60cc8697713701e7659204f4 refs/tags/0.3.3\nb51c25a4367bd17f419f78cb5a27f319e9d820f5 refs/tags/0.3.4\nb265612710cbd5ddb1b173c94ece8ec5c7ceccac refs/tags/0.3.5\ne404bcfe42e92d7509717a2dfa115cacb4964c5d refs/tags/0.3.6\n5e4d0d5b7e7f314dde701c546c4365c59782d3dc refs/tags/0.3.7\ne13f91c9c913d2b81c59adeaad687efa2b35293a refs/tags/0.3.8\n17599625f09af0ae4b525e63ab726a3002540702 refs/tags/0.3.9\n13e907f70571dd146d8dc29ddec4599b40ba4e85 refs/tags/0.4.0\n155a74cf676495df1e0674dd07b5e4a0291a9a4a refs/tags/0.4.1\nf37abccdc148cb02ca637a6f0bc8821491cce358 refs/tags/0.4.2\n0250d29ebdd02f28f9020445adb5a4e51fd1902c refs/tags/0.5.0\n2fb87db6d9f34109a70205876030c53f815739b7 refs/tags/0.5.1\n629d17ba8d6a1a4eca8145eb089ed5bca4473dfc refs/tags/0.6.0\ne926130f5f1b7903f68be49cc1563225bd9d948d refs/tags/0.7.0\n7365303897e6185796c274425c079916047e3f14 refs/tags/0.7.1\na735c4adabeba637409f41c4325dd8fc5fb91e2d refs/tags/0.7.10\nfe023fd27404889c5122f902456cbba14b767405 refs/tags/0.7.11\n4430e72972c77a5e9c1555d59bba11d840682691 refs/tags/0.7.12\nf0e53eb490a9558c7f594d2e095b70665e36ca88 refs/tags/0.7.13\nf6520e25e7c329c2957cda447f149fc6a930db0d refs/tags/0.7.2\nd509762f7191757c240d3c79c9ecda53f8c0cfe3 refs/tags/0.7.3\nc02e7a783d1c42fd1f91bca7142f7c3733950c05 refs/tags/0.7.4\n8c8a9e496e9b86ba7602709438980ca31e6989d9 refs/tags/0.7.5\n29839c18b4ac83c0111a178322b57ebb8a8d402c refs/tags/0.7.6\n3b62973cf74fafd8ea906644d89ac34d29a8a6cf refs/tags/0.7.7\ne67ff99dc43c391e89a37f97a9d298c3428bbde2 refs/tags/0.7.8\n4b72ecda0d40ed8e5ab8ad4095a0691d30ec6cd0 refs/tags/0.7.9\n2512b8cc3d7f001d277e89978da2049a5feee5c4 refs/tags/0.8.0\n86c47029690bd2731d204245f3f54462227bba0d refs/tags/0.9.0\n9a7f94f78588e9b5ba7ca077e1f7eae0607c6cf6 refs/tags/0.9.1\n08c915dc016d16c1dfa9a77d0b045ec29c9f2074 refs/tags/0.9.2\n3fb658b1ce1e1efa37d6f9f14322bdac8def02a5 refs/tags/0.9.3\n738fda0add962379ffe6aa6ca5f01a6943a98a2e refs/tags/0.9.4\n48d821add361f7ad768ecb35a0b19c38f90c919e refs/tags/0.9.5\nff9ae890f597dac301b2ac6e6805eb9ac5afd49a refs/tags/0.9.6\n483c78f06e60b0ec5e79fc3476df075ee7286890 refs/tags/0.9.7\n416eec87a5ae39a1a6035552e9e9a47d76b13026 refs/tags/1.0.0\na935cfe9445cc5218fbdd7e0afb35aa1587fff61 refs/tags/1.0.1\n4b83863a9181f054bb695b11b5d663406dfd85d2 refs/tags/1.0.2\n295145fddaa4fe29c1e71a5044d968a84f9dbf69 refs/tags/1.1.0\n8f74ea4e5718436c47305b4488842e6458a13dac refs/tags/1.1.1\n4135bb291e53d615a976e997c44fb2bd9e1ad343 refs/tags/1.1.10\n8c09dbcd16612f5989065db02ea2e7a752dd2656 refs/tags/1.1.11\naedfebdb6c016431d84b0c07cf181b957a900640 refs/tags/1.1.12\n2c2e958366ef6998115740bdf110588d730e5738 refs/tags/1.1.2\nbecc77258321e6ec40d89efdddf37bafd0d07fc3 refs/tags/1.1.3\ne070d7c9853bf94c35b81cf0c0a8980c2449bb22 refs/tags/1.1.4\n12c986cbbf65e8571a486e9230808bf887e5f04f refs/tags/1.1.5\n63df8986f5b56913b02d26954fa033eeaf43714c refs/tags/1.1.6\n38e02c9c6bd728b043036fe0d1894d774cab3108 refs/tags/1.1.7\n3c3879fff16450d28ade79a6b08982bf5cefc061 refs/tags/1.1.8\ne32b811b3b2e70a1d189d7a663bc2583e9c18f96 refs/tags/1.1.9\n0c1b4277c08197ce7e7e0aa2bad91d909fcd96ac refs/tags/2.0.0\n"),
toData("testes", GitCurrentCommit, 0, "d9db2ad09aa38fc26625341e1b666602959e144f\n"),
toData("testes", GitMergeBase, 0, "d9db2ad09aa38fc26625341e1b666602959e144f\n416eec87a5ae39a1a6035552e9e9a47d76b13026\nd9db2ad09aa38fc26625341e1b666602959e144f\n"),
toData("testes", GitCheckout, 0, "416eec87a5ae39a1a6035552e9e9a47d76b13026"),
toData("grok", GitDiff, 0, ""),
toData("grok", GitTags, 0, "2ca193c31fa2377c1e991a080d60ca3215ff6cf0 refs/tags/0.0.1\n48007554b21ba2f65c726ae2fdda88d621865b4a refs/tags/0.0.2\n7092a0286421c7818cd335cca9ebc72d03d866c2 refs/tags/0.0.3\n62707b8ac684efac35d301dbde57dc750880268e refs/tags/0.0.4\n876f2504e0c2f785ffd2cf65a78e2aea474fa8aa refs/tags/0.0.5\nb7eb1f2501aa2382cb3a38353664a13af62a9888 refs/tags/0.0.6\nf5d818bfd6038884b3d8b531c58484ded20a58a4 refs/tags/0.1.0\n961eaddea49c3144d130d105195583d3f11fb6c6 refs/tags/0.2.0\n15ab8ed8d4f896232a976a9008548bd53af72a66 refs/tags/0.2.1\n426a7d7d4603f77ced658e73ad7f3f582413f6cd refs/tags/0.3.0\n83cf7a39b2fe897786fb0fe01a7a5933c3add286 refs/tags/0.3.1\n8d2e3c900edbc95fa0c036fd76f8e4f814aef2c1 refs/tags/0.3.2\n48b43372f49a3bb4dc0969d82a0fca183fb94662 refs/tags/0.3.3\n9ca947a3009ea6ba17814b20eb953272064eb2e6 refs/tags/0.4.0\n1b5643d04fba6d996a16d1ffc13d034a40003f8f refs/tags/0.5.0\n486b0eb580b1c465453d264ac758cc490c19c33e refs/tags/0.5.1\naedb0d9497390e20b9d2541cef2bb05a5cda7a71 refs/tags/0.5.2\n"),
toData("grok", GitCurrentCommit, 0, "4e6526a91a23eaec778184e16ce9a34d25d48bdc\n"),
toData("grok", GitMergeBase, 0, "4e6526a91a23eaec778184e16ce9a34d25d48bdc\n62707b8ac684efac35d301dbde57dc750880268e\n349c15fd1e03f1fcdd81a1edefba3fa6116ab911\n"),
toData("grok", GitCheckout, 0, "62707b8ac684efac35d301dbde57dc750880268e"),
toData("nim-bytes2human", GitDiff, 0, ""),
toData("nim-bytes2human", GitTags, 0, ""),
toData("nim-bytes2human", GitCurrentcommit, 0, "ec2c1a758cabdd4751a06c8ebf2b923f19e32731\n")
]
#[
Current directory is now E:\atlastest\nim-bytes2human
cmd git diff args [] --> ("", 0)
cmd git show-ref --tags args [] --> ("", 1)
cmd git log -n 1 --format=%H args [] --> (, 0)
[Warning] (nim-bytes2human) package has no tagged releases
nimble E:\atlastest\nim-bytes2human\bytes2human.nimble info (requires: @["nim >= 1.0.0"], srcDir: "src", tasks: @[])
[Error] There were problems.
Error: execution of an external program failed: 'E:\nim\tools\atlas\atlas.exe clone https://github.com/disruptek/balls'
]#

View File

@@ -1,46 +0,0 @@
# Small program that runs the test cases
import std / [strutils, os, sequtils]
from std/private/gitutils import diffFiles
if execShellCmd("nim c -r atlas/versions.nim") != 0:
quit("FAILURE: unit tests in atlas/versions.nim failed")
var failures = 0
when defined(develop):
const atlasExe = "bin" / "atlas".addFileExt(ExeExt)
if execShellCmd("nim c -o:$# atlas/atlas.nim" % [atlasExe]) != 0:
quit("FAILURE: compilation of atlas failed")
else:
const atlasExe = "atlas".addFileExt(ExeExt)
proc exec(cmd: string) =
if execShellCmd(cmd) != 0:
quit "FAILURE: " & cmd
proc sameDirContents(expected, given: string) =
for _, e in walkDir(expected):
let g = given / splitPath(e).tail
if fileExists(g):
if readFile(e) != readFile(g):
echo "FAILURE: files differ: ", e
echo diffFiles(e, g).output
inc failures
else:
echo "FAILURE: file does not exist: ", g
inc failures
proc testWsConflict() =
const myproject = "atlas/tests/ws_conflict/myproject"
createDir(myproject)
exec atlasExe & " --project=" & myproject & " --showGraph --genLock use https://github.com/apkg"
sameDirContents("atlas/tests/ws_conflict/expected", myproject)
removeDir("atlas/tests/ws_conflict/apkg")
removeDir("atlas/tests/ws_conflict/bpkg")
removeDir("atlas/tests/ws_conflict/cpkg")
removeDir("atlas/tests/ws_conflict/dpkg")
removeDir(myproject)
testWsConflict()
if failures > 0: quit($failures & " failures occurred.")

View File

@@ -1,32 +0,0 @@
version = "3.4.1"
author = "disruptek"
description = "a unittest framework with balls 🔴🟡🟢"
license = "MIT"
# requires newTreeFrom
requires "https://github.com/disruptek/grok >= 0.5.0 & < 1.0.0"
requires "https://github.com/disruptek/ups < 1.0.0"
requires "https://github.com/planetis-m/sync#810bd2d"
#requires "https://github.com/c-blake/cligen < 2.0.0"
bin = @["balls"] # build the binary for basic test running
installExt = @["nim"] # we need to install balls.nim also
skipDirs = @["tests"] # so stupid... who doesn't want tests?
#installFiles = @["balls.nim"] # https://github.com/nim-lang/Nim/issues/16661
task test, "run tests for ci":
when defined(windows):
exec "balls.cmd"
else:
exec "balls"
task demo, "produce a demo":
exec "nim c --define:release balls.nim"
when (NimMajor, NimMinor) != (1, 0):
echo "due to nim bug #16307, use nim-1.0"
quit 1
exec """demo docs/demo.svg "nim c --out=\$1 examples/fails.nim""""
exec """demo docs/clean.svg "nim c --define:danger -f --out=\$1 tests/test.nim""""
exec "nim c --define:release --define:ballsDry balls.nim"
exec """demo docs/runner.svg "balls""""

View File

@@ -1,5 +0,0 @@
version = "0.0.4"
author = "disruptek"
description = "don't read too much into it"
license = "MIT"
requires "nim >= 1.0.0"

View File

@@ -1,7 +0,0 @@
version = "0.2.2"
author = "Juan Carlos"
description = "Convert bytes to kilobytes, megabytes, gigabytes, etc."
license = "MIT"
srcDir = "src"
requires "nim >= 1.0.0" # https://github.com/juancarlospaco/nim-bytes2human/issues/2#issue-714338524

View File

@@ -1,10 +0,0 @@
############# begin Atlas config section ##########
--noNimblePath
--path:"../balls"
--path:"../grok"
--path:"../ups"
--path:"../sync"
--path:"../npeg/src"
--path:"../testes"
--path:"../nim-bytes2human/src"
############# end Atlas config section ##########

View File

@@ -1,48 +0,0 @@
# Package
version = "0.24.1"
author = "Ico Doornekamp"
description = "a PEG library"
license = "MIT"
srcDir = "src"
installExt = @["nim"]
# Dependencies
requires "nim >= 0.19.0"
# Test
task test, "Runs the test suite":
exec "nimble testc && nimble testcpp && nimble testarc && nimble testjs"
task testc, "C tests":
exec "nim c -r tests/tests.nim"
task testcpp, "CPP tests":
exec "nim cpp -r tests/tests.nim"
task testjs, "JS tests":
exec "nim js -r tests/tests.nim"
task testdanger, "Runs the test suite in danger mode":
exec "nim c -d:danger -r tests/tests.nim"
task testwin, "Mingw tests":
exec "nim c -d:mingw tests/tests.nim && wine tests/tests.exe"
task test32, "32 bit tests":
exec "nim c --cpu:i386 --passC:-m32 --passL:-m32 tests/tests.nim && tests/tests"
task testall, "Test all":
exec "nimble test && nimble testcpp && nimble testdanger && nimble testjs && nimble testwin"
when (NimMajor, NimMinor) >= (1, 1):
task testarc, "--gc:arc tests":
exec "nim c --gc:arc -r tests/tests.nim"
else:
task testarc, "--gc:arc tests":
exec "true"
task perf, "Test performance":
exec "nim cpp -r -d:danger tests/performance.nim"

View File

@@ -1,36 +0,0 @@
[
{
"name": "bytes2human",
"url": "https://github.com/juancarlospaco/nim-bytes2human",
"method": "git",
"tags": [
"bytes",
"human",
"minimalism",
"size"
],
"description": "Convert bytes to kilobytes, megabytes, gigabytes, etc.",
"license": "LGPLv3",
"web": "https://github.com/juancarlospaco/nim-bytes2human"
},
{
"name": "npeg",
"url": "https://github.com/zevv/npeg",
"method": "git",
"tags": [
"PEG",
"parser",
"parsing",
"regexp",
"regular",
"grammar",
"lexer",
"lexing",
"pattern",
"matching"
],
"description": "PEG (Parsing Expression Grammars) string matching library for Nim",
"license": "MIT",
"web": "https://github.com/zevv/npeg"
}
]

View File

@@ -1,10 +0,0 @@
# Package
version = "1.4.0"
author = "Antonis Geralis"
description = "Useful synchronization primitives."
license = "MIT"
# Deps
requires "nim >= 1.0.0"

View File

@@ -1,23 +0,0 @@
version = "1.0.0"
author = "disruptek"
description = "a cure for salty testes"
license = "MIT"
#requires "cligen >= 0.9.41 & <= 0.9.45"
#requires "bump >= 1.8.18 & < 2.0.0"
requires "https://github.com/disruptek/grok >= 0.0.4 & < 1.0.0"
requires "https://github.com/juancarlospaco/nim-bytes2human"
bin = @["testes"] # build the binary for basic test running
installExt = @["nim"] # we need to install testes.nim also
skipDirs = @["tests"] # so stupid... who doesn't want tests?
task test, "run tests for ci":
exec "nim c --run testes.nim"
task demo, "produce a demo":
when (NimMajor, NimMinor) != (1, 0):
echo "due to nim bug #16307, use nim-1.0"
quit 1
exec """demo docs/demo.svg "nim c --out=\$1 examples/balls.nim""""
exec """demo docs/clean.svg "nim c --define:danger --out=\$1 tests/testicles.nim""""

View File

@@ -1,13 +0,0 @@
version = "0.0.2"
author = "disruptek"
description = "a package handler"
license = "MIT"
requires "npeg >= 0.23.2 & < 1.0.0"
requires "https://github.com/disruptek/testes >= 1.0.0 & < 2.0.0"
task test, "run tests":
when defined(windows):
exec "testes.cmd"
else:
exec findExe"testes"

View File

@@ -1,2 +0,0 @@
deps=""
overrides="url.rules"

View File

@@ -1,20 +0,0 @@
{
"items": {
"apkg": {
"url": "file://./source/apkg",
"commit": "#head"
},
"bpkg": {
"url": "file://./source/bpkg",
"commit": "1.0"
},
"cpkg": {
"url": "file://./source/cpkg",
"commit": "2.0"
},
"dpkg": {
"url": "file://./source/dpkg",
"commit": "1.0"
}
}
}

View File

@@ -1,11 +0,0 @@
digraph deps {
"file://./source/apkg/#head" [label=""];
"file://./source/bpkg/1.0" [label=""];
"file://./source/cpkg/1.0" [label="unused"];
"file://./source/cpkg/2.0" [label=""];
"file://./source/dpkg/1.0" [label=""];
"file://./source/apkg/#head" -> "file://./source/bpkg/1.0";
"file://./source/apkg/#head" -> "file://./source/cpkg/1.0";
"file://./source/bpkg/1.0" -> "file://./source/cpkg/2.0";
"file://./source/cpkg/2.0" -> "file://./source/dpkg/1.0";
}

View File

@@ -1 +0,0 @@
requires "https://github.com/apkg"

View File

@@ -1,7 +0,0 @@
############# begin Atlas config section ##########
--noNimblePath
--path:"../apkg"
--path:"../bpkg"
--path:"../cpkg"
--path:"../dpkg"
############# end Atlas config section ##########

View File

@@ -1,4 +0,0 @@
# require first b and then c
requires "https://github.com/bpkg >= 1.0"
requires "https://github.com/cpkg >= 1.0"

View File

@@ -1 +0,0 @@
requires "https://github.com/cpkg >= 2.0"

View File

@@ -1 +0,0 @@
# No dependency here!

View File

@@ -1 +0,0 @@
requires "https://github.com/dpkg >= 1.0"

View File

@@ -1 +0,0 @@
# empty for now

View File

@@ -1 +0,0 @@
https://github.com/$+ -> file://./source/$#

View File

@@ -1,348 +0,0 @@
#
# Atlas Package Cloner
# (c) Copyright 2021 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import std / [strutils, parseutils, algorithm]
type
Version* = distinct string
VersionRelation* = enum
verGe, # >= V -- Equal or later
verGt, # > V
verLe, # <= V -- Equal or earlier
verLt, # < V
verEq, # V
verAny, # *
verSpecial # #head
VersionReq* = object
r: VersionRelation
v: Version
VersionInterval* = object
a: VersionReq
b: VersionReq
isInterval: bool
template versionKey*(i: VersionInterval): string = i.a.v.string
proc createQueryEq*(v: Version): VersionInterval =
VersionInterval(a: VersionReq(r: verEq, v: v))
proc extractGeQuery*(i: VersionInterval): Version =
if i.a.r in {verGe, verGt, verEq}:
result = i.a.v
else:
result = Version""
proc `$`*(v: Version): string {.borrow.}
proc isSpecial(v: Version): bool =
result = v.string.len > 0 and v.string[0] == '#'
proc isValidVersion*(v: string): bool {.inline.} =
result = v.len > 0 and v[0] in {'#'} + Digits
proc isHead(v: Version): bool {.inline.} = cmpIgnoreCase(v.string, "#head") == 0
template next(l, p, s: untyped) =
if l > 0:
inc p, l
if p < s.len and s[p] == '.':
inc p
else:
p = s.len
else:
p = s.len
proc lt(a, b: string): bool {.inline.} =
var i = 0
var j = 0
while i < a.len or j < b.len:
var x = 0
let l1 = parseSaturatedNatural(a, x, i)
var y = 0
let l2 = parseSaturatedNatural(b, y, j)
if x < y:
return true
elif x == y:
discard "continue"
else:
return false
next l1, i, a
next l2, j, b
result = false
proc `<`*(a, b: Version): bool =
# Handling for special versions such as "#head" or "#branch".
if a.isSpecial or b.isSpecial:
if a.isHead: return false
if b.isHead: return true
# any order will do as long as the "sort" operation moves #thing
# to the bottom:
if a.isSpecial and b.isSpecial:
return a.string < b.string
return lt(a.string, b.string)
proc eq(a, b: string): bool {.inline.} =
var i = 0
var j = 0
while i < a.len or j < b.len:
var x = 0
let l1 = parseSaturatedNatural(a, x, i)
var y = 0
let l2 = parseSaturatedNatural(b, y, j)
if x == y:
discard "continue"
else:
return false
next l1, i, a
next l2, j, b
result = true
proc `==`*(a, b: Version): bool =
if a.isSpecial or b.isSpecial:
result = a.string == b.string
else:
result = eq(a.string, b.string)
proc parseVer(s: string; start: var int): Version =
if start < s.len and s[start] == '#':
var i = start
while i < s.len and s[i] notin Whitespace: inc i
result = Version s.substr(start, i-1)
start = i
elif start < s.len and s[start] in Digits:
var i = start
while i < s.len and s[i] in Digits+{'.'}: inc i
result = Version s.substr(start, i-1)
start = i
else:
result = Version""
proc parseVersion*(s: string; start: int): Version =
var i = start
result = parseVer(s, i)
proc parseSuffix(s: string; start: int; result: var VersionInterval; err: var bool) =
# >= 1.5 & <= 1.8
# ^ we are here
var i = start
while i < s.len and s[i] in Whitespace: inc i
# Nimble doesn't use the syntax `>= 1.5, < 1.6` but we do:
if i < s.len and s[i] in {'&', ','}:
inc i
while i < s.len and s[i] in Whitespace: inc i
if s[i] == '<':
inc i
var r = verLt
if s[i] == '=':
inc i
r = verLe
while i < s.len and s[i] in Whitespace: inc i
result.b = VersionReq(r: r, v: parseVer(s, i))
result.isInterval = true
while i < s.len and s[i] in Whitespace: inc i
# we must have parsed everything:
if i < s.len:
err = true
proc parseVersionInterval*(s: string; start: int; err: var bool): VersionInterval =
var i = start
while i < s.len and s[i] in Whitespace: inc i
result = VersionInterval(a: VersionReq(r: verAny, v: Version""))
if i < s.len:
case s[i]
of '*': result = VersionInterval(a: VersionReq(r: verAny, v: Version""))
of '#', '0'..'9':
result = VersionInterval(a: VersionReq(r: verEq, v: parseVer(s, i)))
if result.a.v.isHead: result.a.r = verAny
err = i < s.len
of '=':
inc i
if i < s.len and s[i] == '=': inc i
while i < s.len and s[i] in Whitespace: inc i
result = VersionInterval(a: VersionReq(r: verEq, v: parseVer(s, i)))
err = i < s.len
of '<':
inc i
var r = verLt
if i < s.len and s[i] == '=':
r = verLe
inc i
while i < s.len and s[i] in Whitespace: inc i
result = VersionInterval(a: VersionReq(r: r, v: parseVer(s, i)))
parseSuffix(s, i, result, err)
of '>':
inc i
var r = verGt
if i < s.len and s[i] == '=':
r = verGe
inc i
while i < s.len and s[i] in Whitespace: inc i
result = VersionInterval(a: VersionReq(r: r, v: parseVer(s, i)))
parseSuffix(s, i, result, err)
else:
err = true
else:
result = VersionInterval(a: VersionReq(r: verAny, v: Version"#head"))
proc parseTaggedVersions*(outp: string): seq[(string, Version)] =
result = @[]
for line in splitLines(outp):
if not line.endsWith("^{}"):
var i = 0
while i < line.len and line[i] notin Whitespace: inc i
let commitEnd = i
while i < line.len and line[i] in Whitespace: inc i
while i < line.len and line[i] notin Digits: inc i
let v = parseVersion(line, i)
if v != Version(""):
result.add (line.substr(0, commitEnd-1), v)
result.sort proc (a, b: (string, Version)): int =
(if a[1] < b[1]: 1
elif a[1] == b[1]: 0
else: -1)
proc matches(pattern: VersionReq; v: Version): bool =
case pattern.r
of verGe:
result = pattern.v < v or pattern.v == v
of verGt:
result = pattern.v < v
of verLe:
result = v < pattern.v or pattern.v == v
of verLt:
result = v < pattern.v
of verEq, verSpecial:
result = pattern.v == v
of verAny:
result = true
proc matches*(pattern: VersionInterval; v: Version): bool =
if pattern.isInterval:
result = matches(pattern.a, v) and matches(pattern.b, v)
else:
result = matches(pattern.a, v)
proc selectBestCommitMinVer*(data: openArray[(string, Version)]; elem: VersionInterval): string =
for i in countdown(data.len-1, 0):
if elem.matches(data[i][1]):
return data[i][0]
return ""
proc selectBestCommitMaxVer*(data: openArray[(string, Version)]; elem: VersionInterval): string =
for i in countup(0, data.len-1):
if elem.matches(data[i][1]): return data[i][0]
return ""
proc toSemVer*(i: VersionInterval): VersionInterval =
result = i
if not result.isInterval and result.a.r in {verGe, verGt}:
var major = 0
let l1 = parseSaturatedNatural(result.a.v.string, major, 0)
if l1 > 0:
result.isInterval = true
result.b = VersionReq(r: verLt, v: Version($(major+1)))
proc selectBestCommitSemVer*(data: openArray[(string, Version)]; elem: VersionInterval): string =
result = selectBestCommitMaxVer(data, elem.toSemVer)
when isMainModule:
template v(x): untyped = Version(x)
assert v"1.0" < v"1.0.1"
assert v"1.0" < v"1.1"
assert v"1.2.3" < v"1.2.4"
assert v"2.0.0" < v"2.0.0.1"
assert v"2.0.0" < v"20.0"
assert not (v"1.10.0" < v"1.2.0")
assert v"1.0" < v"#head"
assert v"#branch" < v"#head"
assert v"#branch" < v"1.0"
assert not (v"#head" < v"#head")
assert not (v"#head" < v"10.0")
const lines = """
24870f48c40da2146ce12ff1e675e6e7b9748355 1.6.12
b54236aaee2fc90200cb3a4e7070820ced9ce605 1.6.10
f06dc8ee3baf8f64cce67a28a6e6e8a8cd9bf04b 1.6.8
2f85924354af35278a801079b7ff3f8805ff1f5a 1.6.6
007bf1cb52eac412bc88b3ca2283127ad578ec04 1.6.4
ee18eda86eef2db0a49788bf0fc8e35996ba7f0d 1.6.2
1a2a82e94269741b0d8ba012994dd85a53f36f2d 1.6.0
074f7159752b0da5306bdedb3a4e0470af1f85c0 1.4.8
4eb05ebab2b4d8b0cd00b19a72af35a2d767819a 1.4.6
944c8e6d04a044611ed723391272f3c86781eadd 1.4.4
cd090a6151b452b99d65c5173400d4685916f970 1.4.2
01dd8c7a959adac4aa4d73abdf62cbc53ffed11b 1.4.0
1420d508dc4a3e51137647926d4db2f3fa62f43c 1.2.18
726e3bb1ffc6bacfaab0a0abf0209640acbac807 1.2.16
80d2206e68cd74020f61e23065c7a22376af8de5 1.2.14
ddfe3905964fe3db33d7798c6c6c4a493cbda6a3 1.2.12
6d914b7e6edc29c3b8ab8c0e255bd3622bc58bba 1.2.10
0d1a9f5933eab686ab3b527b36d0cebd3949a503 1.2.8
a5a0a9e3cb14e79d572ba377b6116053fc621f6d 1.2.6
f9829089b36806ac0129c421bf601cbb30c2842c 1.2.4
8b03d39fd387f6a59c97c2acdec2518f0b18a230 1.2.2
a8a4725850c443158f9cab38eae3e54a78a523fb 1.2.0
8b5888e0545ee3d931b7dd45d15a1d8f3d6426ef 1.0.10
7282e53cad6664d09e8c9efd0d7f263521eda238 1.0.8
283a4137b6868f1c5bbf0dd9c36d850d086fa007 1.0.6
e826ff9b48af376fdc65ba22f7aa1c56dc169b94 1.0.4
4c33037ef9d01905130b22a37ddb13748e27bb7c 1.0.2
0b6866c0dc48b5ba06a4ce57758932fbc71fe4c2 1.0.0
a202715d182ce6c47e19b3202e0c4011bece65d8 0.20.2
8ea451196bd8d77b3592b8b34e7a2c49eed784c9 0.20.0
1b512cc259b262d06143c4b34d20ebe220d7fb5c 0.19.6
be22a1f4e04b0fec14f7a668cbaf4e6d0be313cb 0.19.4
5cbc7f6322de8460cc4d395ed0df6486ae68004e 0.19.2
79934561e8dde609332239fbc8b410633e490c61 0.19.0
9c53787087e36b1c38ffd670a077903640d988a8 0.18.0
a713ffd346c376cc30f8cc13efaee7be1b8dfab9 0.17.2
2084650f7bf6f0db6003920f085e1a86f1ea2d11 0.17.0
f7f68de78e9f286b704304836ed8f20d65acc906 0.16.0
48bd4d72c45f0f0202a0ab5ad9d851b05d363988 0.15.2
dbee7d55bc107b2624ecb6acde7cabe4cb3f5de4 0.15.0
0a4854a0b7bcef184f060632f756f83454e9f9de 0.14.2
5333f2e4cb073f9102f30aacc7b894c279393318 0.14.0
7e50c5b56d5b5b7b96e56b6c7ab5e104124ae81b 0.13.0
49bce0ebe941aafe19314438fb724c081ae891aa 0.12.0
70789ef9c8c4a0541ba24927f2d99e106a6fe6cc 0.11.2
79cc0cc6e501c8984aeb5b217a274877ec5726bc 0.11.0
46d829f65086b487c08d522b8d0d3ad36f9a2197 0.10.2
9354d3de2e1ecc1747d6c42fbfa209fb824837c0 0.9.6
6bf5b3d78c97ce4212e2dd4cf827d40800650c48 0.9.4
220d35d9e19b0eae9e7cd1f1cac6e77e798dbc72 0.9.2
7a70058005c6c76c92addd5fc21b9706717c75e3 0.9.0
32b4192b3f0771af11e9d850046e5f3dd42a9a5f 0.8.14
"""
proc p(s: string): VersionInterval =
var err = false
result = parseVersionInterval(s, 0, err)
assert not err
let tags = parseTaggedVersions(lines)
let query = p">= 1.2 & < 1.4"
assert selectBestCommitMinVer(tags, query) == "a8a4725850c443158f9cab38eae3e54a78a523fb"
let query2 = p">= 1.2 & < 1.4"
assert selectBestCommitMaxVer(tags, query2) == "1420d508dc4a3e51137647926d4db2f3fa62f43c"
let query3 = p">= 0.20.0"
assert selectBestCommitSemVer(tags, query3) == "a202715d182ce6c47e19b3202e0c4011bece65d8"
let query4 = p"#head"
assert selectBestCommitSemVer(tags, query4) == "24870f48c40da2146ce12ff1e675e6e7b9748355"

View File

@@ -66,7 +66,6 @@ Files: "doc"
Files: "doc/html"
Files: "tools"
Files: "tools/debug/nim-gdb.py"
Files: "atlas"
Files: "nimpretty"
Files: "testament"
Files: "nimsuggest"

View File

@@ -1,188 +0,0 @@
# Atlas Package Cloner
Atlas is a simple package cloner tool. It manages an isolated workspace that
contains projects and dependencies.
Atlas is compatible with Nimble in the sense that it supports the Nimble
file format.
## Concepts
Atlas uses three concepts:
1. Workspaces
2. Projects
3. Dependencies
### Workspaces
Every workspace is isolated, nothing is shared between workspaces.
A workspace is a directory that has a file `atlas.workspace` inside it. Use `atlas init`
to create a workspace out of the current working directory.
Projects plus their dependencies are stored in a workspace:
```
$workspace / main project
$workspace / other project
$workspace / _deps / dependency A
$workspace / _deps / dependency B
```
The deps directory can be set via `--deps:DIR` during `atlas init`.
### Projects
A workspace contains one or multiple "projects". These projects can use each other and it
is easy to develop multiple projects at the same time.
### Dependencies
Inside a workspace there can be a `_deps` directory where your dependencies are kept. It is
easy to move a dependency one level up and out the `_deps` directory, turning it into a project.
Likewise, you can move a project to the `_deps` directory, turning it into a dependency.
The only distinction between a project and a dependency is its location. For dependency resolution
a project always has a higher priority than a dependency.
## No magic
Atlas works by managing two files for you, the `project.nimble` file and the `nim.cfg` file. You can
edit these manually too, Atlas doesn't touch what should be left untouched.
## How it works
Atlas uses git commits internally; version requirements are translated
to git commits via `git show-ref --tags`.
Atlas uses URLs internally; Nimble package names are translated to URLs
via Nimble's `packages.json` file.
Atlas does not call the Nim compiler for a build, instead it creates/patches
a `nim.cfg` file for the compiler. For example:
```
############# begin Atlas config section ##########
--noNimblePath
--path:"../nimx"
--path:"../sdl2/src"
--path:"../opengl/src"
############# end Atlas config section ##########
```
The version selection is deterministic, it picks up the *minimum* required
version. Thanks to this design, lock files are much less important.
## Commands
Atlas supports the following commands:
## Use <url> / <package name>
Clone the package behind `url` or `package name` and its dependencies into
the `_deps` directory and make it available for your current project which
should be in the current working directory. Atlas will create or patch
the files `$project.nimble` and `nim.cfg` for you so that you can simply
import the required modules.
For example:
```
mkdir newproject
cd newproject
git init
atlas use lexim
# add `import lexim` to your example.nim file
nim c example.nim
```
### Clone/Update <url>/<package name>
Clones a URL and all of its dependencies (recursively) into the workspace.
Creates or patches a `nim.cfg` file with the required `--path` entries.
**Note**: Due to the used algorithms an `update` is the same as a `clone`.
If a `<package name>` is given instead the name is first translated into an URL
via `packages.json` or via a github search.
### Search <term term2 term3 ...>
Search the package index `packages.json` for a package that the given terms
in its description (or name or list of tags).
### Install <proj.nimble>
Use the .nimble file to setup the project's dependencies.
### UpdateProjects / updateDeps [filter]
Update every project / dependency in the workspace that has a remote URL that
matches `filter` if a filter is given. The project / dependency is only updated
if there are no uncommitted changes.
### Others
Run `atlas --help` for more features.
### Overrides
You can override how Atlas resolves a package name or a URL. The overrides use
a simple pattern matching language and are flexible enough to integrate private
gitlab repositories.
To setup an override file, edit the `$workspace/atlas.workspace` file to contain
a line like `overrides="urls.rules"`. Then create a file `urls.rules` that can
contain lines like:
```
customProject -> https://gitlab.company.com/customProject
https://github.com/araq/ormin -> https://github.com/useMyForkInstead/ormin
```
The `$` has a special meaning in a pattern:
================= ========================================================
``$$`` Matches a single dollar sign.
``$*`` Matches until the token following the ``$*`` was found.
The match is allowed to be of 0 length.
``$+`` Matches until the token following the ``$+`` was found.
The match must consist of at least one char.
``$s`` Skips optional whitespace.
================= ========================================================
For example, here is how to override any github link:
```
https://github.com/$+ -> https://utopia.forall/$#
```
You can use `$1` or `$#` to refer to captures.
### Virtual Nim environments
Atlas supports setting up a virtual Nim environment via the `env` command. You can
even install multiple different Nim versions into the same workspace.
For example:
```
atlas env 1.6.12
atlas env devel
```
When completed, run `source nim-1.6.12/activate.sh` on UNIX and `nim-1.6.12/activate.bat` on Windows.

View File

@@ -11,6 +11,7 @@
const
NimbleStableCommit = "168416290e49023894fc26106799d6f1fc964a2d" # master
AtlasStableCommit = "#head"
# examples of possible values: #head, #ea82b54, 1.2.3
FusionStableHash = "#372ee4313827ef9f2ea388840f7d6b46c2b1b014"
ChecksumsStableCommit = "b4c73320253f78e3a265aec6d9e8feb83f97c77b"
@@ -72,6 +73,7 @@ Possible Commands:
e.g. nimble)
doesn't require network connectivity
nimble builds the Nimble tool
atlas builds the Atlas tool
fusion installs fusion via Nimble
Boot options:
@@ -156,6 +158,14 @@ proc bundleNimbleExe(latest: bool, args: string) =
nimCompile("dist/nimble/src/nimble.nim",
options = "-d:release --mm:refc --noNimblePath " & args)
proc bundleAtlasExe(latest: bool, args: string) =
let commit = if latest: "HEAD" else: AtlasStableCommit
cloneDependency(distDir, "https://github.com/nim-lang/atlas.git",
commit = commit, allowBundled = true)
# installer.ini expects it under $nim/bin
nimCompile("dist/atlas/src/atlas.nim",
options = "-d:release --noNimblePath " & args)
proc bundleNimsuggest(args: string) =
nimCompileFold("Compile nimsuggest", "nimsuggest/nimsuggest.nim",
options = "-d:danger " & args)
@@ -179,7 +189,6 @@ proc bundleWinTools(args: string) =
buildVccTool(args)
nimCompile("tools/nimgrab.nim", options = "-d:ssl " & args)
nimCompile("tools/nimgrep.nim", options = args)
nimCompile("atlas/atlas.nim", options = args)
nimCompile("testament/testament.nim", options = args)
when false:
# not yet a tool worth including
@@ -193,6 +202,7 @@ proc bundleChecksums(latest: bool) =
proc zip(latest: bool; args: string) =
bundleChecksums(latest)
bundleNimbleExe(latest, args)
bundleAtlasExe(latest, args)
bundleNimsuggest(args)
bundleNimpretty(args)
bundleWinTools(args)
@@ -236,21 +246,17 @@ proc buildTools(args: string = "") =
"--opt:speed --stacktrace -d:debug --stacktraceMsgs -d:nimCompilerStacktraceHints " & args,
outputName = "nim_dbg")
nimCompileFold("Compile atlas", "atlas/atlas.nim", options = "-d:release " & args,
outputName = "atlas")
proc testTools(args: string = "") =
nimCompileFold("Compile nimgrep", "tools/nimgrep.nim",
options = "-d:release " & args)
when defined(windows): buildVccTool(args)
bundleNimpretty(args)
nimCompileFold("Compile testament", "testament/testament.nim", options = "-d:release " & args)
nimCompileFold("Compile atlas", "atlas/atlas.nim", options = "-d:release " & args,
outputName = "atlas")
proc nsis(latest: bool; args: string) =
bundleChecksums(latest)
bundleNimbleExe(latest, args)
bundleAtlasExe(latest, args)
bundleNimsuggest(args)
bundleWinTools(args)
# make sure we have generated the niminst executables:
@@ -612,12 +618,6 @@ proc runCI(cmd: string) =
execFold("build nimsuggest_testing", "nim c -o:bin/nimsuggest_testing -d:release nimsuggest/nimsuggest")
execFold("Run nimsuggest tests", "nim r nimsuggest/tester")
execFold("Run atlas tests", "nim c -r -d:atlasTests atlas/atlas.nim clone https://github.com/disruptek/balls")
# compile it again to get rid of `-d:atlasTests`:
nimCompileFold("Compile atlas", "atlas/atlas.nim", options = "-d:release ",
outputName = "atlas")
execFold("Run more atlas tests", "nim c -r atlas/tester.nim")
kochExecFold("Testing booting in refc", "boot -d:release --mm:refc -d:nimStrictMode --lib:lib")
@@ -731,6 +731,7 @@ when isMainModule:
of "xtemp": xtemp(op.cmdLineRest)
of "wintools": bundleWinTools(op.cmdLineRest)
of "nimble": bundleNimbleExe(latest, op.cmdLineRest)
of "atlas": bundleAtlasExe(latest, op.cmdLineRest)
of "nimsuggest": bundleNimsuggest(op.cmdLineRest)
# toolsNoNimble is kept for backward compatibility with build scripts
of "toolsnonimble", "toolsnoexternal":
@@ -738,6 +739,7 @@ when isMainModule:
of "tools":
buildTools(op.cmdLineRest)
bundleNimbleExe(latest, op.cmdLineRest)
bundleAtlasExe(latest, op.cmdLineRest)
of "checksums":
bundleChecksums(latest)
of "pushcsource":

View File

@@ -2,7 +2,7 @@
## (c) 2021 Andreas Rumpf
import std / strutils
import ".." / compiler / [ast, idents, msgs, syntaxes, options, pathutils]
import ".." / ".." / compiler / [ast, idents, msgs, syntaxes, options, pathutils]
type
NimbleFileInfo* = object