You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support asconfig.json in addition to CLI arguments #1230
This reminds me that #1134 is somewhat related in that it proposes an asbuild cli utility, with profiles for debug, release or custom. Perhaps there are ways to make these two work well together?
Another nice touch might be to allow the contents of asconfig.json to be, as a fallback if it's not present, part of tsconfig.json as the assembly key. How useful that'll be ultimately depends a bit, but since we have portable AssemblyScript that compiles to both JS and Wasm, which most likely won't go away, it seems good to have.
sourceMap?: boolean is a string. Relative source map if specified without an argument (--sourceMap, string empty), otherwise absolute source map using the specified URL (--sourceMap URL). Perhaps this can be improved to also take a true instead of an empty string.
Binaryen passes are lowercase and use dashes, or do we postprocess these from uppercase camelcase?
What do these do? include?: string[]; exclude?: string[]; extends?: string[];
sourceMap?: boolean is a string. Relative source map if specified without an argument (--sourceMap, string empty), otherwise absolute source map using the specified URL (--sourceMap URL). Perhaps this can be improved to also take a true instead of an empty string.
See edit, switched to boolean | string.
Binaryen passes are lowerdashcase
Got it. Will change it.
What do these do? include?: string[]; exclude?: string[]; extends?: string[];
All of these were copied from the idea of what the tsconfig does, but we have entry points, so instead I replaced them with an entry?: string[] property.
Have been brainstorming with @jtenner on Slack, and this was the latest we came up with:
Let every project have an asconfig.json in its main directory. Like TypeScript, it has a compilerOptions entry specifying the options used for compilation:
{
"compilerOptions": {
...
}
}
The configuration can extend another configuration using the extends key, using node resolution:
{
"extends": "./path/to/other/asconfig.json"
}
Now, while one doesn't typically have the need for multiple builds in TypeScript, it is fairly common to build two variants in AssemblyScript. To make this easier and reduce the amount of files one has to deal with, extending this with multiple targets seems convenient:
{
"compilerOptions": {
// common options used by all targets
},
"targets": {
"release": {
// additional release options
},
"debug": {
// additional debug options
}
}
}
This feature would be optional, in that if the targets key is not present, just compilerOptions will be used and function just as one would expect from TypeScript (can have multiple files, one per target if one so wishes). Iff the targets key is present, the default target to build would be the first specified (here: release), issuing a warning on the console "No target specified: Defaulting to 'release'".
On the command line, one would either specify just the config file via --config ./path/to/asbuild.json or, if targets is present, --config ./path/to/asbuild.json:release to execute a single one, --config ./path/to/asbuild.json:release,debug to execute multiple or --config ./path/to/asbuild.json:* to execute all. Similarly, if such a config is extended, one would either
{
"extends": "./path/to/asconfig.json"
}
or, if targets is present,
{
"extends": "./path/to/asconfig.json:release"
}
If targets is present and the former is used, so a default target is executed, a warning on the console should read "No target specified for './path/to/asconfig.json': Defaulting to 'release'.".
Thoughts? The obvious alternative would be to omit the targets mechanism, but then tooling might have problems determining which asconfig.x.json is the correct one, unless the default one should always be named asconfig.json with additional ones being possible?
Also it would be nice to have nested projects so that multiple binaries can be generated. This is particularly of interest to Near with projects with multiple smart contracts.
My thinking there is that one typically has two builds per project, like one debug and one release. Without targets, it is strictly necessary to have multiple files, like
where it seems just too easy to overlook something due to having to switch through the files, instead of having a clear view on all the options at once.
Then there is
Also it would be nice to have nested projects so that multiple binaries can be generated
which is impossible to do (in a single command) without targets, since every config makes exactly one binary.
I think this newer approach looks promising, but may become easier if we can join our efforts. Allow me to add a little bit of context, and see whether you think my proposal makes sense.
After discovering some rather silly limitations of the current package.json file, and having some discussions with @dcodeIO, I ended up writing a new tool called asbuild. My original basis was the Rust ecosystem, which has a tool called cargo (which was largely based on npm).
Instead of managing packages, this tool is the main interface between the dev and the compiler. When you run asbuild, you tell it two things:
A build profile: general properties of the output artifacts, grouped around what the dev is trying to achieve (debug symbols, optimizations, assertions, etc).
A build target: what artifact is expected to be output: which binary if there is more than one, or assembly versus an executable. (I am new to JS and WebAssembly, so I am not well versed in this area.)
While asbuild would support a set of defaults, per-project settings make sense in an asconfig.json file. It is equivalent in the Rust ecosystem to Cargo.toml, or package.json with npm.
The key is: those settings are their own abstraction. How they work -- what options they pass to the compiler -- should be allowed to change between toolchain versions. The compiler can change its flags, but so long as asbuild changes to match, developers will get what they expect.
Manually adding compiler flags directly may be necessary, so that should be possible, but awkward. Intentionally so. Most of the time, the dev should not be thinking at that level.
To conclude, I think having a single asconfig.json (or perhaps one per target) would serve as great input to asbuild. It would contain all the information necessary for the project -- all the targets supported and non-default options for all profiles -- and let asbuild work out the asc command line to achieve it.
I don't think this affects much of what you have described so far, except perhaps to put more knowledge about the compiler into asbuild, rather than the configuration itself.
My prototype was an MVP, and there is a lot more it could/should do. You seem to have a better grasp of things, so any suggestions or info you have to improve it would help.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Activity
dcodeIO commentedon Apr 17, 2020
This reminds me that #1134 is somewhat related in that it proposes an
asbuildcli utility, with profiles for debug, release or custom. Perhaps there are ways to make these two work well together?Another nice touch might be to allow the contents of
asconfig.jsonto be, as a fallback if it's not present, part oftsconfig.jsonas theassemblykey. How useful that'll be ultimately depends a bit, but since we have portable AssemblyScript that compiles to both JS and Wasm, which most likely won't go away, it seems good to have.jtenner commentedon Apr 18, 2020
EDIT: I will try to keep this updated with the latest iteration as per suggestions.
We can use this as a starting point. I went through the CLI help and generated an asconfig.json shape.
Any suggestions?
dcodeIO commentedon Apr 18, 2020
Nice! A few comments:
sourceMap?: booleanis astring. Relative source map if specified without an argument (--sourceMap, string empty), otherwise absolute source map using the specified URL (--sourceMap URL). Perhaps this can be improved to also take atrueinstead of an empty string.include?: string[]; exclude?: string[]; extends?: string[];jtenner commentedon Apr 18, 2020
See edit, switched to
boolean | string.Got it. Will change it.
All of these were copied from the idea of what the tsconfig does, but we have entry points, so instead I replaced them with an
entry?: string[]property.Perhaps there is no need for asconfig extension.
dcodeIO commentedon Apr 18, 2020
Have been brainstorming with @jtenner on Slack, and this was the latest we came up with:
Let every project have an
asconfig.jsonin its main directory. Like TypeScript, it has acompilerOptionsentry specifying the options used for compilation:{ "compilerOptions": { ... } }The configuration can extend another configuration using the
extendskey, using node resolution:{ "extends": "./path/to/other/asconfig.json" }Now, while one doesn't typically have the need for multiple builds in TypeScript, it is fairly common to build two variants in AssemblyScript. To make this easier and reduce the amount of files one has to deal with, extending this with multiple targets seems convenient:
{ "compilerOptions": { // common options used by all targets }, "targets": { "release": { // additional release options }, "debug": { // additional debug options } } }This feature would be optional, in that if the
targetskey is not present, justcompilerOptionswill be used and function just as one would expect from TypeScript (can have multiple files, one per target if one so wishes). Iff thetargetskey is present, the default target to build would be the first specified (here: release), issuing a warning on the console "No target specified: Defaulting to 'release'".On the command line, one would either specify just the config file via
--config ./path/to/asbuild.jsonor, iftargetsis present,--config ./path/to/asbuild.json:releaseto execute a single one,--config ./path/to/asbuild.json:release,debugto execute multiple or--config ./path/to/asbuild.json:*to execute all. Similarly, if such a config is extended, one would either{ "extends": "./path/to/asconfig.json" }or, if targets is present,
{ "extends": "./path/to/asconfig.json:release" }If targets is present and the former is used, so a default target is executed, a warning on the console should read "No target specified for './path/to/asconfig.json': Defaulting to 'release'.".
Thoughts? The obvious alternative would be to omit the
targetsmechanism, but then tooling might have problems determining whichasconfig.x.jsonis the correct one, unless the default one should always be namedasconfig.jsonwith additional ones being possible?jtenner commentedon Apr 19, 2020
Specifying the first "key" as the target is undefined behavior in js. Object keys are not garunteed to be ordered.
Suggesting to use an Array instead, and always use the first one.
willemneal commentedon Apr 20, 2020
Typescript currently allows the extend to use node package resolution.
willemneal commentedon Apr 20, 2020
Also it would be nice to have nested projects so that multiple binaries can be generated. This is particularly of interest to Near with projects with multiple smart contracts.
jtenner commentedon Apr 20, 2020
@dcodeIO I am suggesting this:
{ "options": {}, "targets": [ { "name": "release", "options": { ... } } ] }You cannot default to the "first" one, if it's only object keys. Can we resolve this first before I start work?
dcodeIO commentedon Apr 20, 2020
Hmm, with that, we could even do something fancy like:
{ "targets": [ { "name": "release", "extends": "assemblyscript/presets:release", "options": { ... } }, { "name": "debug", "extends": "assemblyscript/presets:debug", "options": { ... } } ] }but raises the question whether we still need top-level
options?jtenner commentedon Apr 21, 2020
Again. Why is it so inconvenient or wrong to just have single asconfig files per target?
dcodeIO commentedon Apr 21, 2020
My thinking there is that one typically has two builds per project, like one debug and one release. Without
targets, it is strictly necessary to have multiple files, likewhere it seems just too easy to overlook something due to having to switch through the files, instead of having a clear view on all the options at once.
Then there is
which is impossible to do (in a single command) without
targets, since every config makes exactly one binary.jtenner commentedon Apr 21, 2020
Right. I'm arguing for simplicity and leaving the complexity for end users.
I am now proposing a recursive configuration algorithm and exactly two cli options with defaults specified below.
Steps:
jtenner commentedon Apr 21, 2020
I'm sorry this is taking so long. Encapsulating this algorithm feels quite complicated. 😅
jhwgh1968 commentedon Apr 26, 2020
@jtenner, I am the author of the
asbuildPR, who was just sent over here.I think this newer approach looks promising, but may become easier if we can join our efforts. Allow me to add a little bit of context, and see whether you think my proposal makes sense.
After discovering some rather silly limitations of the current
package.jsonfile, and having some discussions with @dcodeIO, I ended up writing a new tool calledasbuild. My original basis was the Rust ecosystem, which has a tool calledcargo(which was largely based onnpm).Instead of managing packages, this tool is the main interface between the dev and the compiler. When you run
asbuild, you tell it two things:While
asbuildwould support a set of defaults, per-project settings make sense in anasconfig.jsonfile. It is equivalent in the Rust ecosystem toCargo.toml, orpackage.jsonwith npm.The key is: those settings are their own abstraction. How they work -- what options they pass to the compiler -- should be allowed to change between toolchain versions. The compiler can change its flags, but so long as asbuild changes to match, developers will get what they expect.
Manually adding compiler flags directly may be necessary, so that should be possible, but awkward. Intentionally so. Most of the time, the dev should not be thinking at that level.
To conclude, I think having a single
asconfig.json(or perhaps one per target) would serve as great input toasbuild. It would contain all the information necessary for the project -- all the targets supported and non-default options for all profiles -- and let asbuild work out theasccommand line to achieve it.I don't think this affects much of what you have described so far, except perhaps to put more knowledge about the compiler into asbuild, rather than the configuration itself.
My prototype was an MVP, and there is a lot more it could/should do. You seem to have a better grasp of things, so any suggestions or info you have to improve it would help.
stale commentedon May 26, 2020
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
jtenner commentedon May 27, 2020
I am taking a break from open source development for a while, and I don't want this issue to die, because it's important to AssemblyScript.
I have a few more thoughts before I leave this issue up for grabs:
[-]asconfig.json - Working Issue RFC[/-][+]Support asconfig.json in addition to CLI arguments[/+]MaxGraey commentedon Aug 8, 2020
@jtenner Do we need keep opened this issue?
jtenner commentedon Aug 8, 2020
No. I think our needs are covered.