@naanlang/naan 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +3 -4
- package/README.md +20 -2
- package/bin/index.js +2 -2
- package/dist/env_web.js +86 -17
- package/dist/naan.min.js +7 -7
- package/frameworks/browser/browser.nlg +26 -2
- package/frameworks/browser/sworker.js +17 -17
- package/frameworks/browser/workers.nlg +7 -0
- package/frameworks/client/psm_client.nlg +1 -0
- package/frameworks/common/common.nlg +33 -5
- package/frameworks/node/filesystem.nlg +32 -26
- package/frameworks/node/gitter.nlg +9 -4
- package/frameworks/node/https_request.nlg +19 -14
- package/frameworks/project/build.nlg +177 -68
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/running.nlg +32 -10
- package/frameworks/storage/psm.nlg +20 -4
- package/lib/browser/env_web.js +90 -21
- package/lib/core/naanlib.js +7 -7
- package/package.json +1 -1
- package/plugins/serviceAws/aws/aws-sdk-node.min.js +1 -1
- package/plugins/serviceAws/aws/aws-sdk.min.js +1 -1
- package/plugins/serviceAws/aws/lambda_ws_init.nlg +2 -1
- package/plugins/serviceAws/aws_dynamo.nlg +27 -20
- package/plugins/serviceAws/aws_dynextra.nlg +110 -5
- package/plugins/serviceAws/aws_lambda.nlg +4 -8
- package/plugins/serviceAws/aws_sqs.nlg +113 -0
- package/plugins/serviceAws/serviceAws.nlg +1 -1
- package/plugins/serviceYC/generic_api.yaml +36 -0
- package/plugins/serviceYC/naanide-relay-index.js +148 -0
- package/plugins/serviceYC/serviceYC.nlg +59 -0
- package/plugins/serviceYC/yc_function.nlg +161 -0
- package/test/test_01_core.nlg +2 -2
- package/test/test_02_context.nlg +2 -2
- package/test/test_05_strings.nlg +11 -1
- package/test/test_06_lingoparse.nlg +43 -14
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2023 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -47,6 +47,20 @@
|
|
|
47
47
|
* srcpath - the source path in common to all sources
|
|
48
48
|
* destpath - the destination path in common to all outputs
|
|
49
49
|
*
|
|
50
|
+
* Special paths:
|
|
51
|
+
* srcpath - the Build object looks for all sources within the srcpath specified when it's
|
|
52
|
+
* instantiated. For example, the files in a group are located in the join of the
|
|
53
|
+
* paths: <srcpath> / <group.input> / <srcname.xx>.
|
|
54
|
+
* destpath - the Build object writes all output files within the destpath specified when
|
|
55
|
+
* it's instantiated. For example, the files output from a group are located in
|
|
56
|
+
* the join of the paths: <destpath> / <group.output> / <srcname.xx>. Note that
|
|
57
|
+
* group.input is used to locate the files, but is not part of the output.
|
|
58
|
+
* @ - the @ character stands in for a persistent, temporary directory within the
|
|
59
|
+
* build folder that replaces srcpath or destpath. It can be used in fields that
|
|
60
|
+
* are otherwise absolute: group.input, group.output, and template paths. Build
|
|
61
|
+
* detects piplines formed from temporary files and processes them in order from
|
|
62
|
+
* beginning to end.
|
|
63
|
+
*
|
|
50
64
|
* Templates:
|
|
51
65
|
* A dictionary where each key is a destfile as described above, and the data for the key
|
|
52
66
|
* is the path to a template file relative to srcpath. When a template file exists for multiple-
|
|
@@ -76,6 +90,7 @@
|
|
|
76
90
|
* licfile: <license file, path relative to srcpath>
|
|
77
91
|
* verfile: <version file, path relative to srcpath>
|
|
78
92
|
* buildno: <build number file, path relative to srcpath>
|
|
93
|
+
* xvrfile: <external version file, path relative to srcpath>
|
|
79
94
|
* run: {
|
|
80
95
|
* "open": "Nide_LaunchMac.tool",
|
|
81
96
|
* "args": []
|
|
@@ -129,6 +144,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
129
144
|
build = new(object, this)
|
|
130
145
|
build.srcpath = srcpath
|
|
131
146
|
build.destpath = destpath
|
|
147
|
+
build.intpath = JSpath.join(destpath, "tmp")
|
|
132
148
|
build.tasks = { // all tasks counter
|
|
133
149
|
copy: 0,
|
|
134
150
|
version: 0,
|
|
@@ -152,11 +168,16 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
152
168
|
build.verfilepath = JSpath.join(build.srcpath, rules.verfile)
|
|
153
169
|
if rules.buildno
|
|
154
170
|
build.buildnopath = JSpath.join(build.srcpath, rules.buildno)
|
|
171
|
+
if rules.xvrfile
|
|
172
|
+
build.xvrfilepath = JSpath.join(build.srcpath, rules.xvrfile)
|
|
155
173
|
if rules.templates { // templates for catenates
|
|
156
174
|
let (tpath, writepath) {
|
|
157
175
|
build.tepaths = { } // template for each catenate output
|
|
158
176
|
for tpath in rules.templates {
|
|
159
|
-
|
|
177
|
+
if tpath.startsWith("@")
|
|
178
|
+
writepath = JSpath.join(build.intpath, tpath.substring(1))
|
|
179
|
+
else
|
|
180
|
+
writepath = JSpath.join(build.destpath, tpath)
|
|
160
181
|
build.tepaths[writepath] = JSpath.join(build.srcpath, rules.templates[tpath])
|
|
161
182
|
}
|
|
162
183
|
build.testats = { }
|
|
@@ -616,7 +637,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
616
637
|
}
|
|
617
638
|
|
|
618
639
|
groups = new(build.groups) // copy so we can append more groups as needed
|
|
619
|
-
sourcemax =
|
|
640
|
+
sourcemax = 10000
|
|
620
641
|
catenates = { } // catenate groups
|
|
621
642
|
pending = new(nonce)
|
|
622
643
|
pending.active = 0
|
|
@@ -635,11 +656,18 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
635
656
|
groupVerStat, source, sdex) {
|
|
636
657
|
++pending.active
|
|
637
658
|
future(function test1() {
|
|
638
|
-
if group.input
|
|
659
|
+
if group.input.startsWith("@") { // intermediate directory
|
|
660
|
+
group.intSource = true
|
|
661
|
+
indirpath = JSpath.join(build.intpath, group.input.substring(1))
|
|
662
|
+
}
|
|
663
|
+
else if group.input
|
|
639
664
|
indirpath = JSpath.join(build.srcpath, group.input)
|
|
640
665
|
else
|
|
641
666
|
indirpath = build.srcpath
|
|
642
|
-
|
|
667
|
+
if group.output.startsWith("@")
|
|
668
|
+
outdirpath = JSpath.join(build.intpath, group.output.substring(1))
|
|
669
|
+
else
|
|
670
|
+
outdirpath = JSpath.join(build.destpath, group.output)
|
|
643
671
|
destcheck = new(group.destcheck).reverse() // get next destination to check
|
|
644
672
|
groupVerStat = verfileStat
|
|
645
673
|
if group.depend_buildno {
|
|
@@ -655,11 +683,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
655
683
|
else
|
|
656
684
|
outfile = JSpath.join(outdirpath, source)
|
|
657
685
|
fs.info(infile, false, function(error, instat, local listing, addgroup, file) {
|
|
658
|
-
if error
|
|
659
|
-
build.errorlist.push(error)
|
|
660
|
-
else if instat.type != "directory"
|
|
661
|
-
addEntry(infile, outfile, instat, sdex) // add execution entry if needed
|
|
662
|
-
else { // add a new group for directory source
|
|
686
|
+
if !error && instat.type == "directory" {
|
|
663
687
|
`(error, listing) = fs.dirList(infile, { stat: true })
|
|
664
688
|
if error
|
|
665
689
|
build.errorlist.push(error)
|
|
@@ -681,6 +705,10 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
681
705
|
groups.push(addgroup)
|
|
682
706
|
}
|
|
683
707
|
}
|
|
708
|
+
else if !error || group.intSource
|
|
709
|
+
addEntry(infile, outfile, instat, sdex) // add execution entry
|
|
710
|
+
else
|
|
711
|
+
build.errorlist.push(error)
|
|
684
712
|
--pending.active
|
|
685
713
|
doMore()
|
|
686
714
|
})
|
|
@@ -692,11 +720,17 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
692
720
|
// Add an entry to execution list if it's needed.
|
|
693
721
|
//
|
|
694
722
|
closure addEntry(infile, outfile, instat, sdex, local error, outstat, entry) {
|
|
723
|
+
if sdex >= sourcemax {
|
|
724
|
+
build.errorlist.push(Error("Too many sources in one group:", groupno.group))
|
|
725
|
+
return
|
|
726
|
+
}
|
|
695
727
|
entry = {
|
|
696
728
|
readpath: infile,
|
|
697
729
|
writepath: outfile
|
|
698
730
|
}
|
|
699
|
-
if group.input
|
|
731
|
+
if group.input.startsWith("@")
|
|
732
|
+
entry.insource = JSpath.join(group.input.substring(1), group.sources[sdex])
|
|
733
|
+
else if group.input // insource is the name within zip/cat
|
|
700
734
|
entry.insource = JSpath.join(group.input, group.sources[sdex])
|
|
701
735
|
else
|
|
702
736
|
entry.insource = group.sources[sdex]
|
|
@@ -771,23 +805,24 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
771
805
|
++pending.active
|
|
772
806
|
if destcheck { // destcheck is special target for determining if task needed
|
|
773
807
|
entry.destcheck = JSpath.join(outdirpath, destcheck.pop())
|
|
774
|
-
fs.info(entry.destcheck, false,
|
|
808
|
+
fs.info(entry.destcheck, false, addOne)
|
|
775
809
|
} else
|
|
776
|
-
fs.info(outfile, false,
|
|
810
|
+
fs.info(outfile, false, addOne)
|
|
777
811
|
|
|
778
|
-
function
|
|
812
|
+
function addOne(error, outstat, local entryop) {
|
|
779
813
|
if error || toint(instat.mtimeMs) > toint(outstat.mtimeMs) {
|
|
814
|
+
entry.outOfDate = true
|
|
780
815
|
catenates[entry.writepath] = true // this entire group needed
|
|
781
|
-
build.filelist.push(entry)
|
|
816
|
+
build.filelist.push(entry)
|
|
782
817
|
entryop = "make:"
|
|
783
818
|
} else if entry.catorder {
|
|
784
819
|
build.filelist.push(entry) // needed if any in group out of date
|
|
785
|
-
entryop = "
|
|
820
|
+
entryop = "cat-check:"
|
|
786
821
|
}
|
|
787
822
|
else
|
|
788
823
|
entryop = "up-to-date:"
|
|
789
824
|
if debugMake
|
|
790
|
-
debuglog(entryop, entry.*, instat.mtimeMs, outstat.mtimeMs, entry.
|
|
825
|
+
debuglog(entryop, entry.readpath, entry.*, instat.mtimeMs, outstat.mtimeMs, entry.writepath)
|
|
791
826
|
--pending.active
|
|
792
827
|
doMore()
|
|
793
828
|
}
|
|
@@ -808,6 +843,32 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
808
843
|
doMore()
|
|
809
844
|
pending.wait()
|
|
810
845
|
|
|
846
|
+
//
|
|
847
|
+
// Cross-check inputs from intermediate files that will be built
|
|
848
|
+
//
|
|
849
|
+
|
|
850
|
+
let (outint, entry) {
|
|
851
|
+
outint = {}
|
|
852
|
+
for entry in build.filelist
|
|
853
|
+
if entry.outOfDate && entry.writepath.startsWith(build.intpath) {
|
|
854
|
+
outint[entry.writepath] = entry // at least one component out of date
|
|
855
|
+
break
|
|
856
|
+
}
|
|
857
|
+
for entry in build.filelist
|
|
858
|
+
if outint[entry.writepath].catorder > entry.catorder
|
|
859
|
+
outint[entry.writepath] = entry // find first component
|
|
860
|
+
for entry in build.filelist
|
|
861
|
+
if outint[entry.readpath] {
|
|
862
|
+
entry.outOfDate = true
|
|
863
|
+
catenates[entry.writepath] = true // this entire group needed
|
|
864
|
+
entry.depends = outint[entry.readpath]
|
|
865
|
+
if !entry.depends.done
|
|
866
|
+
entry.depends.done = new(nonce)
|
|
867
|
+
if debugMake
|
|
868
|
+
debuglog("add-make:", entry.readpath, entry.*, entry.writepath)
|
|
869
|
+
}
|
|
870
|
+
} ()
|
|
871
|
+
|
|
811
872
|
//
|
|
812
873
|
// Remove unneeded catenate entries and index the remainder
|
|
813
874
|
//
|
|
@@ -820,11 +881,16 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
820
881
|
else if catenates[entry.writepath] {
|
|
821
882
|
if !renumber[entry.writepath]
|
|
822
883
|
renumber[entry.writepath] = []
|
|
823
|
-
renumber[entry.writepath].
|
|
884
|
+
if renumber[entry.writepath].indexOf(entry) < 0
|
|
885
|
+
renumber[entry.writepath].push(entry) // this catenate is needed
|
|
886
|
+
entry.outOfDate = true // this entry is needed
|
|
824
887
|
true
|
|
825
888
|
} else
|
|
826
889
|
false // this one is not
|
|
827
890
|
})
|
|
891
|
+
build.filelist = build.filelist.filter(function(entry) {
|
|
892
|
+
entry.outOfDate
|
|
893
|
+
})
|
|
828
894
|
for wpath in renumber { // assign entries in catorder
|
|
829
895
|
renumber[wpath].sort(function(a,b) { a.catorder <=> b.catorder })
|
|
830
896
|
catindex = 0
|
|
@@ -845,8 +911,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
845
911
|
// checked and any that have all the parts are written out. Catenates that don't have all their
|
|
846
912
|
// parts are reported as an error in addition to the error that caused them to be incomplete.
|
|
847
913
|
//
|
|
848
|
-
closure execute(local error, licFileDefs, buildno, verFileDefs,
|
|
849
|
-
|
|
914
|
+
closure execute(local error, licFileDefs, buildno, verFileDefs, xvrFileDefs,
|
|
915
|
+
entries, pending, baddestpaths, catenates) {
|
|
850
916
|
if build.tasks.license > 0
|
|
851
917
|
`(error, licFileDefs) = readSubstitutionFile(build.licfilepath)
|
|
852
918
|
if build.tasks.version > 0 {
|
|
@@ -857,9 +923,15 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
857
923
|
} else
|
|
858
924
|
build.buildno = buildno = toint(buildno.trim())
|
|
859
925
|
build.buildno = buildno
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
926
|
+
if build.xvrfilepath {
|
|
927
|
+
`(error, xvrFileDefs) = readSubstitutionFile(build.xvrfilepath)
|
|
928
|
+
if error
|
|
929
|
+
build.errorlist.push(error)
|
|
930
|
+
}
|
|
931
|
+
if !xvrFileDefs
|
|
932
|
+
xvrFileDefs = { }
|
|
933
|
+
xvrFileDefs.BuildNumber = buildno
|
|
934
|
+
`(error, verFileDefs) = readSubstitutionFile(build.verfilepath, xvrFileDefs)
|
|
863
935
|
build.version = verFileDefs["Version"]
|
|
864
936
|
verFileDefs["CacheBuster"] = HashMD5(build.version.concat(Math.random()))
|
|
865
937
|
}
|
|
@@ -889,6 +961,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
889
961
|
closure processOneFile(entry, local result, content, error) {
|
|
890
962
|
++pending.active
|
|
891
963
|
future(function build1(local dirpath) {
|
|
964
|
+
if entry.depends
|
|
965
|
+
entry.depends.done.wait() // wait for our precursor
|
|
892
966
|
dirpath = JSpath.dirname(entry.writepath)
|
|
893
967
|
if baddestpaths[dirpath]
|
|
894
968
|
{ } // error already reported
|
|
@@ -904,7 +978,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
904
978
|
erase: true // not really needed
|
|
905
979
|
overwrite: true // overwrite files
|
|
906
980
|
force: true // ignore modify date
|
|
907
|
-
|
|
981
|
+
idmode: true // preserve ids and mode
|
|
908
982
|
})
|
|
909
983
|
if error // deepcopy returns a list of errors
|
|
910
984
|
error = error.0 // but we're only doing one item
|
|
@@ -936,10 +1010,20 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
936
1010
|
if !catenates[entry.writepath]
|
|
937
1011
|
catenates[entry.writepath] = new(Array(entry.catcount))
|
|
938
1012
|
entry.content = content
|
|
939
|
-
catenates[entry.writepath][entry.catindex] = entry
|
|
940
|
-
|
|
1013
|
+
catenates[entry.writepath][entry.catindex] = entry
|
|
1014
|
+
if catReady(entry.writepath) {
|
|
1015
|
+
`(error, result) = writeCatenate(entry.writepath)
|
|
1016
|
+
if error
|
|
1017
|
+
build.errorlist.push(error)
|
|
1018
|
+
catenates[entry.writepath].0.done.signal(error)
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
941
1022
|
`(error, result) = fs.writeFile(entry.writepath, content)
|
|
942
|
-
|
|
1023
|
+
entry.done.signal(error)
|
|
1024
|
+
}
|
|
1025
|
+
} else
|
|
1026
|
+
entry.done.signal(error)
|
|
943
1027
|
}
|
|
944
1028
|
if error
|
|
945
1029
|
build.errorlist.push(error)
|
|
@@ -960,52 +1044,76 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
960
1044
|
if pending.remaining > 0
|
|
961
1045
|
pending.wait() // don't wait if nothing to do
|
|
962
1046
|
|
|
1047
|
+
// catReady
|
|
963
1048
|
//
|
|
964
|
-
//
|
|
1049
|
+
// Return true iff the catenate has all its elements.
|
|
965
1050
|
//
|
|
1051
|
+
function catReady(writepath, local entry) {
|
|
1052
|
+
for entry in catenates[writepath]
|
|
1053
|
+
if !entry.content
|
|
1054
|
+
return (false)
|
|
1055
|
+
true
|
|
1056
|
+
}
|
|
966
1057
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1058
|
+
// writeCatenate
|
|
1059
|
+
//
|
|
1060
|
+
// Write out a catenate, returning a standard result tuple.
|
|
1061
|
+
//
|
|
1062
|
+
function writeCatenate(writepath,
|
|
1063
|
+
local template, entry, content, catsub, dozip, docat, fsoptions, zipmap, error, result) {
|
|
1064
|
+
template = build.templates[writepath] // optional in some cases ### should warn in others
|
|
1065
|
+
catsub = { }
|
|
1066
|
+
for entry in catenates[writepath] { // error check and substitution build
|
|
1067
|
+
if !entry.content
|
|
1068
|
+
return (list(Error("Incomplete zip/cat:", writepath)))
|
|
1069
|
+
catsub[entry.insource] = entry.content
|
|
1070
|
+
if entry.zip
|
|
1071
|
+
dozip = true
|
|
1072
|
+
if entry.catenate
|
|
1073
|
+
docat = true
|
|
1074
|
+
}
|
|
1075
|
+
if docat { // catenate the files
|
|
1076
|
+
if dozip
|
|
1077
|
+
return (list(Error("Cannot combine zip/cat into:", writepath)))
|
|
1078
|
+
if template {
|
|
1079
|
+
`(content, result) = applySubstitutions(template, catsub)
|
|
1080
|
+
if length(catsub) != result
|
|
1081
|
+
return (list(Error("Matched ", result, " of ", length(catsub),
|
|
1082
|
+
"substitutions in template:", build.tepaths[writepath])))
|
|
980
1083
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
}
|
|
988
|
-
else
|
|
989
|
-
content = catenates[writepath].map(function(entry){entry.content}).join("\n")
|
|
990
|
-
if dozip {
|
|
991
|
-
zipmap = { }
|
|
992
|
-
zipmap[JSpath.basename(writepath)] = content
|
|
993
|
-
`(error, content) = zip(zipmap) // compress the catenated file
|
|
994
|
-
}
|
|
995
|
-
} else {
|
|
996
|
-
if template
|
|
997
|
-
zipmap = applyZipTemplate(template, catsub)
|
|
998
|
-
else
|
|
999
|
-
zipmap = trimZipPaths(catsub)
|
|
1000
|
-
`(error, content) = zip(zipmap) // compress each of the files
|
|
1084
|
+
else
|
|
1085
|
+
content = catenates[writepath].map(function(entry){entry.content}).join("\n")
|
|
1086
|
+
if dozip {
|
|
1087
|
+
zipmap = { }
|
|
1088
|
+
zipmap[JSpath.basename(writepath)] = content
|
|
1089
|
+
`(error, content) = zip(zipmap) // compress the catenated file
|
|
1001
1090
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1091
|
+
} else {
|
|
1092
|
+
if template
|
|
1093
|
+
zipmap = applyZipTemplate(template, catsub)
|
|
1094
|
+
else
|
|
1095
|
+
zipmap = trimZipPaths(catsub)
|
|
1096
|
+
`(error, content) = zip(zipmap) // compress each of the files
|
|
1008
1097
|
}
|
|
1098
|
+
if dozip
|
|
1099
|
+
fsoptions = { encoding: "base64" }
|
|
1100
|
+
if !error
|
|
1101
|
+
`(error, result) = fs.writeFile(writepath, content, fsoptions)
|
|
1102
|
+
if error
|
|
1103
|
+
list(error)
|
|
1104
|
+
else
|
|
1105
|
+
list(false, { ok: true })
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
//
|
|
1109
|
+
// Check for any incomplete catenates.
|
|
1110
|
+
//
|
|
1111
|
+
|
|
1112
|
+
let (writepath, entry) {
|
|
1113
|
+
for writepath in catenates
|
|
1114
|
+
for entry in catenates[writepath]
|
|
1115
|
+
if !entry.content
|
|
1116
|
+
build.errorlist.push(Error("Missing zip/cat element", writepath, "--", entry.readpath))
|
|
1009
1117
|
} ()
|
|
1010
1118
|
}
|
|
1011
1119
|
|
|
@@ -1086,7 +1194,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1086
1194
|
`(error, executor) = track.spawn(build.runway.spawn.0, build.runway.spawn.1, "Build-".concat(build.buildnum), {
|
|
1087
1195
|
startup: {
|
|
1088
1196
|
initcmds: maintext
|
|
1089
|
-
dirpath:
|
|
1197
|
+
dirpath: fs.path.resolve(fs.path.sep, fs.rootpath, build.destpath)
|
|
1090
1198
|
}
|
|
1091
1199
|
})
|
|
1092
1200
|
if error
|
|
@@ -1136,6 +1244,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1136
1244
|
`(error, site) = track.spawn("V-Site", build.runway."v-site", fs, vpath)
|
|
1137
1245
|
if error
|
|
1138
1246
|
return (list(Error("Builder: cannot create virtual site", error)))
|
|
1247
|
+
sleep(1) // needed on Windows or it won't open, fiik why
|
|
1139
1248
|
window = js.w.open(url, title, features)
|
|
1140
1249
|
list(false, { ok: true }) // we don't know the executor
|
|
1141
1250
|
}
|
|
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
|
|
|
296
296
|
*
|
|
297
297
|
* Nide.proj/
|
|
298
298
|
* nide_cliser.cfg - JSON definition of the project (see below)
|
|
299
|
-
* NaanIDE_version.txt - [default] substitution file defining 1.0.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.0.8+1 etc.
|
|
300
300
|
* NaanIDE_version_builds.txt - [default] contains current build number as decimal string
|
|
301
301
|
* build/ - [optional] default build output location
|
|
302
302
|
* NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2021 by Richard C. Zulch
|
|
9
|
+
* Copyright (c) 2021-2023 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -48,17 +48,26 @@ function baseproc(procdef) {
|
|
|
48
48
|
/*
|
|
49
49
|
* pathmatch
|
|
50
50
|
*
|
|
51
|
-
* Given a parent symbol and a tuple of child
|
|
52
|
-
*
|
|
51
|
+
* Given a parent symbol and a tuple of child procedures within it, return the child procedure
|
|
52
|
+
* named by the path in the tuple. Each element in the child procedures is either a symbol == to the
|
|
53
|
+
* procedure or, in the case of lambdas, a tuple comprising the procedure symbol and an integer
|
|
54
|
+
* specifying the nth matching child. This is necessary because a procedure can have any number of
|
|
55
|
+
* children named lambda, and we need to pick the right ones even though we don't have identical
|
|
56
|
+
* symbols.
|
|
53
57
|
*
|
|
54
58
|
*/
|
|
55
59
|
|
|
56
|
-
function pathmatch(parent, path, local segment) {
|
|
60
|
+
function pathmatch(parent, path, local segment, nth, child) {
|
|
57
61
|
if empty(path)
|
|
58
62
|
return (parent)
|
|
59
|
-
segment =
|
|
63
|
+
segment = pop(path)
|
|
64
|
+
if tuple(segment) { // select nth instance of matching symbol
|
|
65
|
+
nth = segment.1
|
|
66
|
+
segment = segment.0
|
|
67
|
+
} else
|
|
68
|
+
nth = 0
|
|
60
69
|
for child in parent@\.children
|
|
61
|
-
if
|
|
70
|
+
if child == segment && nth-- == 0
|
|
62
71
|
return (pathmatch(child, path))
|
|
63
72
|
false
|
|
64
73
|
};
|
|
@@ -68,14 +77,27 @@ function pathmatch(parent, path, local segment) {
|
|
|
68
77
|
* procpath
|
|
69
78
|
*
|
|
70
79
|
* Return a tuple of parent prcoedure symbols for the specified child procedure. Note that this
|
|
71
|
-
* path includes the parent but pathmatch above requires the parent as a separate argument.
|
|
80
|
+
* path includes the parent but pathmatch above requires the parent as a separate argument. As noted
|
|
81
|
+
* above, the segments of the path are either a procedure symbol, or a tuple of symbol and integer.
|
|
72
82
|
*
|
|
73
83
|
*/
|
|
74
84
|
|
|
75
|
-
function procpath(procdef, local path) {
|
|
85
|
+
function procpath(procdef, local path, segment, parent, peers, nth, peer) {
|
|
76
86
|
loop {
|
|
77
|
-
|
|
78
|
-
parent =
|
|
87
|
+
segment = procdef.1
|
|
88
|
+
parent = segment@\.parent
|
|
89
|
+
if segment == lambda && parent { // lambdas all have same name
|
|
90
|
+
peers = parent@\.children
|
|
91
|
+
nth = 0
|
|
92
|
+
for peer in peers {
|
|
93
|
+
if peer === segment
|
|
94
|
+
break
|
|
95
|
+
if peer == segment
|
|
96
|
+
++nth
|
|
97
|
+
}
|
|
98
|
+
push(list(segment, nth), path) // we are the nth of the matching ones
|
|
99
|
+
} else
|
|
100
|
+
push(segment, path)
|
|
79
101
|
if !parent
|
|
80
102
|
break
|
|
81
103
|
procdef = parent.proc
|
|
@@ -248,8 +248,8 @@ closure MakePSMutil(fs, local util) {
|
|
|
248
248
|
// erase: <boolean> -- remove extraneous files in destination folders
|
|
249
249
|
// force: <boolean> -- copy files even if older (default is only copy if new/newer)
|
|
250
250
|
// follow: <boolean> -- follow links instead of treating them as files
|
|
251
|
-
//
|
|
252
|
-
//
|
|
251
|
+
// idmode: <boolean> -- preserve id/mode where possible
|
|
252
|
+
// times: <boolean> -- preserve time where possible
|
|
253
253
|
// }
|
|
254
254
|
//
|
|
255
255
|
// Limitations:
|
|
@@ -336,7 +336,8 @@ closure MakePSMutil(fs, local util) {
|
|
|
336
336
|
//
|
|
337
337
|
// Pass 3 - copy files and links
|
|
338
338
|
//
|
|
339
|
-
asyncArray(copies, 10, closure cpfiles(entry, index, elements,
|
|
339
|
+
asyncArray(copies, 10, closure cpfiles(entry, index, elements,
|
|
340
|
+
local error, data, dest, instat, outstat) {
|
|
340
341
|
`(error, instat) = fs.info(entry.source, fsopt)
|
|
341
342
|
if !error {
|
|
342
343
|
`(error, outstat) = outfs.info(entry.dest)
|
|
@@ -348,6 +349,13 @@ closure MakePSMutil(fs, local util) {
|
|
|
348
349
|
error = Error("deepcopy: can't overwrite", entry.dest)
|
|
349
350
|
else if instat.type == "symlink" && !options.follow {
|
|
350
351
|
`(error, data) = fs.readlink(entry.source)
|
|
352
|
+
if !error {
|
|
353
|
+
`(error, dest) = outfs.readlink(entry.dest) // get destination to compare links
|
|
354
|
+
if dest == data
|
|
355
|
+
return // symlink unchanged
|
|
356
|
+
outfs.delete(entry.dest)
|
|
357
|
+
error = false // ignore any destination errors
|
|
358
|
+
}
|
|
351
359
|
if !error
|
|
352
360
|
`(error, data) = outfs.symlink(data, entry.dest)
|
|
353
361
|
}
|
|
@@ -355,8 +363,16 @@ closure MakePSMutil(fs, local util) {
|
|
|
355
363
|
`(error, data) = fs.readFile(entry.source, { encoding: "binary"})
|
|
356
364
|
if !error
|
|
357
365
|
`(error, data) = outfs.writeFile(entry.dest, data, { encoding: "binary"})
|
|
358
|
-
if !error && options.
|
|
366
|
+
if !error && (options.idmode || options.times) {
|
|
367
|
+
if !options.idmode
|
|
368
|
+
instat.mode = instat.uid = instat.gid = false
|
|
369
|
+
if !options.times {
|
|
370
|
+
instat.mtimeMs = instat.mtime = false
|
|
371
|
+
instat.nodejs_stat.mtimeMs = instat.nodejs_stat.mtime = false
|
|
372
|
+
instat.nodejs_stat.atimeMs = instat.nodejs_stat.atime = false
|
|
373
|
+
}
|
|
359
374
|
`(error) = outfs.setInfo(entry.dest, instat)
|
|
375
|
+
}
|
|
360
376
|
}
|
|
361
377
|
}
|
|
362
378
|
if error
|