-
-
Notifications
You must be signed in to change notification settings - Fork 671
Support asconfig.json #1238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support asconfig.json #1238
Changes from 67 commits
67d8013
6a70013
4cf1b2b
0115341
cb6e9ac
f071ae8
dd12c9a
6f98121
d637a1f
ef481e5
483cc9d
9f602b1
ca95430
3257573
e05a71f
a0700c6
4dd142e
3b5a8ce
2a4e351
9e0d217
7155d50
a7a3999
4e3de7d
3e39805
932961d
a29f617
2ead5ae
c6af0dd
ec7d44c
d3abe65
acd8725
8195764
f30d456
7e26838
d8bd07b
7827a93
3e0303d
bb4cdaf
f44491c
ac37a14
a77826c
7c4e5cf
2ef00d0
3ad6d88
ca18d62
7f25365
dc55518
cbcb88e
9e35892
42703a1
0f1803d
b177e94
e80cd8b
d3a347d
2495578
ad7d24a
9e4aebf
debc2fc
00e9b27
d304b36
16bfe42
bc24391
27656af
e2bf925
8f5e8fb
55135bc
1b1fc19
62caba3
0d0e29e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ out/ | |
raw/ | ||
.history | ||
*.backup | ||
.vscode |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -194,7 +194,8 @@ exports.main = function main(argv, options, callback) { | |
if (!stderr) throw Error("'options.stderr' must be specified"); | ||
|
||
const opts = optionsUtil.parse(argv, exports.options); | ||
const args = opts.options; | ||
let args = opts.options; | ||
|
||
argv = opts.arguments; | ||
if (args.noColors) { | ||
colorsUtil.stdout.supported = | ||
|
@@ -270,6 +271,91 @@ exports.main = function main(argv, options, callback) { | |
|
||
// Set up base directory | ||
const baseDir = args.baseDir ? path.resolve(args.baseDir) : "."; | ||
const target = args.target; | ||
|
||
// Once the baseDir is calculated, we can resolve the config, and its extensions | ||
let asconfig = getAsconfig(args.config, baseDir, readFile); | ||
let asconfigDir = baseDir; | ||
|
||
const seenAsconfig = new Set(); | ||
seenAsconfig.add(path.join(baseDir, args.config)); | ||
|
||
while (asconfig) { | ||
// merge target first, then merge options, then merge extended asconfigs | ||
if (asconfig.targets && asconfig.targets[target]) { | ||
args = optionsUtil.merge(exports.options, asconfig.targets[target], args); | ||
} | ||
if (asconfig.options) { | ||
if (asconfig.options.transform) { | ||
// ensure that a transform's path is relative to the current config | ||
asconfig.options.transform = asconfig.options.transform.map(p => { | ||
if (!path.isAbsolute(p)) { | ||
if (p.startsWith(".")) { | ||
return path.join(asconfigDir, p); | ||
} | ||
return require.resolve(p); | ||
} | ||
return p; | ||
}); | ||
} | ||
args = optionsUtil.merge(exports.options, args, asconfig.options); | ||
} | ||
|
||
// entries are added to the compilation | ||
if (asconfig.entries) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There could also be a workspace field, which could each have its own There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or should this been it's own higher level cli like cargo? |
||
for (const entry of asconfig.entries) { | ||
argv.push( | ||
path.isAbsolute(entry) | ||
? entry | ||
// the entry is relative to the asconfig directory | ||
: path.join(asconfigDir, entry) | ||
); | ||
} | ||
} | ||
|
||
// asconfig "extends" another config, merging options of it's parent | ||
if (asconfig.extends) { | ||
asconfigDir = path.isAbsolute(asconfig.extends) | ||
// absolute extension path means we know the exact directory and location | ||
? path.dirname(asconfig.extends) | ||
// relative means we need to calculate a relative asconfigDir | ||
: path.join(asconfigDir, path.dirname(asconfig.extends)); | ||
const fileName = path.basename(asconfig.extends); | ||
const filePath = path.join(asconfigDir, fileName); | ||
if (seenAsconfig.has(filePath)) { | ||
asconfig = null; | ||
} else { | ||
seenAsconfig.add(filePath); | ||
asconfig = getAsconfig(fileName, asconfigDir, readFile); | ||
} | ||
} else { | ||
asconfig = null; // finished resolving the configuration chain | ||
} | ||
} | ||
|
||
// If showConfig print args and exit | ||
if (args.showConfig) { | ||
stderr.write(JSON.stringify(args, null, 2)); | ||
return callback(null); | ||
} | ||
|
||
// This method resolves a path relative to the baseDir instead of process.cwd() | ||
function resolve(arg) { | ||
if (path.isAbsolute(arg)) return arg; | ||
jtenner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return path.resolve(baseDir, arg); | ||
} | ||
|
||
// create a unique set of values | ||
function unique(values) { | ||
return [...new Set(values)]; | ||
} | ||
|
||
// returns a relative path from baseDir | ||
function makeRelative(arg) { | ||
return path.relative(baseDir, arg); | ||
} | ||
// postprocess we need to get absolute file locations argv | ||
argv = unique(argv.map(resolve)).map(makeRelative); | ||
|
||
// Set up options | ||
const compilerOptions = assemblyscript.newOptions(); | ||
|
@@ -347,7 +433,7 @@ exports.main = function main(argv, options, callback) { | |
const transforms = []; | ||
if (args.transform) { | ||
let tsNodeRegistered = false; | ||
let transformArgs = args.transform; | ||
let transformArgs = unique(args.transform.map(resolve)); | ||
for (let i = 0, k = transformArgs.length; i < k; ++i) { | ||
let filename = transformArgs[i].trim(); | ||
if (!tsNodeRegistered && filename.endsWith(".ts")) { // ts-node requires .ts specifically | ||
|
@@ -376,6 +462,7 @@ exports.main = function main(argv, options, callback) { | |
} | ||
} | ||
} | ||
|
||
function applyTransform(name, ...args) { | ||
for (let i = 0, k = transforms.length; i < k; ++i) { | ||
let transform = transforms[i]; | ||
|
@@ -400,11 +487,12 @@ exports.main = function main(argv, options, callback) { | |
assemblyscript.parse(program, exports.libraryFiles[libPath], exports.libraryPrefix + libPath + extension.ext, false); | ||
}); | ||
}); | ||
const customLibDirs = []; | ||
let customLibDirs = []; | ||
if (args.lib) { | ||
let lib = args.lib; | ||
if (typeof lib === "string") lib = lib.split(","); | ||
Array.prototype.push.apply(customLibDirs, lib.map(lib => lib.trim())); | ||
if (typeof lib === "string") lib = lib.trim().split(/\s*,\s*/); | ||
customLibDirs.push(...lib.map(resolve)); | ||
customLibDirs = unique(customLibDirs); // `lib` and `customLibDirs` may include duplicates | ||
for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom | ||
let libDir = customLibDirs[i]; | ||
let libFiles; | ||
|
@@ -574,7 +662,7 @@ exports.main = function main(argv, options, callback) { | |
const filename = argv[i]; | ||
|
||
let sourcePath = String(filename).replace(/\\/g, "/").replace(extension.re, "").replace(/[\\/]$/, ""); | ||
|
||
// Setting the path to relative path | ||
sourcePath = path.isAbsolute(sourcePath) ? path.relative(baseDir, sourcePath) : sourcePath; | ||
|
||
|
@@ -925,6 +1013,56 @@ exports.main = function main(argv, options, callback) { | |
} | ||
}; | ||
|
||
const toString = Object.prototype.toString; | ||
|
||
function isObject(arg) { | ||
return toString.call(arg) === "[object Object]"; | ||
} | ||
|
||
function getAsconfig(file, baseDir, readFile) { | ||
const contents = readFile(file, baseDir); | ||
const location = path.join(baseDir, file); | ||
if (!contents) return null; | ||
|
||
// obtain the configuration | ||
let config; | ||
try { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. asconfig validation could probably look differently. Do you have any suggestions, or is this good? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking just the top-level entries used by asconfig itself seems good, just the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
config = JSON.parse(contents); | ||
} catch(ex) { | ||
throw new Error("Asconfig is not valid json: " + location); | ||
} | ||
|
||
// validate asconfig shape | ||
if (config.options && !isObject(config.options)) { | ||
throw new Error("Asconfig.options is not an object: " + location); | ||
} | ||
|
||
if (config.include && !Array.isArray(config.include)) { | ||
throw new Error("Asconfig.include is not an array: " + location); | ||
} | ||
|
||
if (config.targets) { | ||
if (!isObject(config.targets)) { | ||
throw new Error("Asconfig.targets is not an object: " + location); | ||
} | ||
const targets = Object.keys(config.targets); | ||
for (let i = 0; i < targets.length; i++) { | ||
const target = targets[i]; | ||
if (!isObject(config.targets[target])) { | ||
throw new Error("Asconfig.targets." + target + " is not an object: " + location); | ||
} | ||
} | ||
} | ||
|
||
if (config.extends && typeof config.extends !== "string") { | ||
throw new Error("Asconfig.extends is not a string: " + location); | ||
} | ||
|
||
return config; | ||
} | ||
|
||
exports.getAsconfig = getAsconfig; | ||
|
||
/** Checks diagnostics emitted so far for errors. */ | ||
function checkDiagnostics(program, stderr) { | ||
var diagnostic; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"targets": { | ||
"release": { | ||
"optimize": true, | ||
"runtime": "stub", | ||
"initialMemory": 30, | ||
"explicitStart": true, | ||
"measure": true, | ||
"pedantic": true | ||
} | ||
}, | ||
"options": { | ||
"initialMemory": 100, | ||
"enable": ["simd"] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
assert(ASC_OPTIMIZE_LEVEL == 3); | ||
assert(ASC_SHRINK_LEVEL == 1); | ||
assert(ASC_FEATURE_SIMD); | ||
let size = memory.size(); | ||
trace("size", 1, size); | ||
assert(size == 30); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"test": "node ../index.js" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "./extends.json" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
assert(true); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "./asconfig.json" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"test": "node ../index.js" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"entries": ["assembly/globals.ts"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// @ts-ignore: decorator | ||
@global const answerToLife = 42; | ||
assert(answerToLife); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
assert(answerToLife == 42); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "../asconfig.json" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
assert(answerToLife == 42); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"test": "node ../../index.js" | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.