Actual Behaviour
After building ClojureScript with {{./script/build}}, {{src/main/cljs/cljs/core.cljs}} and {{src/main/clojure/cljs/util.cljc}} are modified with ClojureScript version numbers. It is a minor annoyance, and a source of confusion for newcomers, to avoid committing these version number changes.
Desired Behaviour
At the very least, this ticket will result in documenting the behaviour and provide a record of the exploration. At best, it will do away with the annoyance.
Dependencies
CLJS-3098 - I'll address Windows bash/sh issues first to allow full verification here.
Discussion on slack
A chat with dnolen on slack:
1. do nothing and document
1. maybe build in a separate directory
1. have a look at what Clojure does
Analysis of Current Behaviour
What does Clojure do?
- Clojure versions are changed explicitly by hand in (link: https://github.com/clojure/clojure/blob/master/pom.xml text: pom.xml).
- The build process transfers this information to {{clojure/version.properties}}
- At runtime, version info is parsed from {{clojure/version.properties}} and made available via (link: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*clojure-version* text: *clojure-version* map) and (link: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/clojure-version text: clojure-version function (which returns string))
What does ClojureScript do?
- In (link: https://github.com/clojure/clojurescript/blob/master/script/build text: script/build):
#1. ClojureScript major and minor versions are changed explicitly by hand, but its incremental version (aka revision aka qualifier) is calculated as the number of commits since major.minor for each build.
- The ClojureScript version is then updated in {{pom.xml}}, {{src/main/clojure/cljs/util.cljc}} and {{src/main/cljs/cljs/core.cljs}}.
- At runtime, there is no special action needed, the versions are hardcoded in the source and available through (link: http://cljs.github.io/api/cljs.core/#STARclojurescript-versionSTAR text: *clojurescript-version* string) and the internal (link: https://github.com/clojure/clojurescript/blob/d6f8896452b531a273f99f2716aaa08f09600063/src/main/clojure/cljs/util.cljc#L20 text: *clojurescript-version* map) and (link: https://github.com/clojure/clojurescript/blob/d6f8896452b531a273f99f2716aaa08f09600063/src/main/clojure/cljs/util.cljc#L46 text: clojurescript-version function (which returns string)).
Also of interest:
1. If you depend on ClojureScript itself as a Git dep, then it is perforce used without the benefit of a "hardcoded" version number in its source. In this case, a hash of the source is used to create the version number in the form of 0.0.hash. Although this is not likely relevant to this ticket, it is worth keeping in mind while exploring solutions.
Approaches
The ClojureScript approach of parsing the version from a file at runtime might work fine on the clojure/cljs side but on the cljs/cljs side reading from a file is at best problematic. I think we should stick with current scheme of replacing version directly in sources.
I like dnolen's idea of building from a separate directory and currently see 2 variations:
1. Copy entire source tree to fresh new directory
1. Copy only source that is altered with version numbers to a fresh new directory and ensure it is found first in classpath when building.
After some experimentation, I have found option 1 to be the gentler touch and less invasive to build config.
Implementation notes
- In {{script/build}} and {{script/uberjar}}, we fixup versions in {{src/main/cljs/cljs/core.aot.js}} and {{src/main/cljs/cljs/core.cljs.cache.aot.edn}} but careful testing show these fixups are no-ops so they have been deleted.
- {{script/build}} and {{script/uberjar}} were very similar. I have kept both files, but consolidated the code under {{script/build}}.
- {{script/revision}} is stale, uses an old version algorithm and is coded to v1.9. My assumption is that this file is unused and it has been deleted.
Assumptions
- CI server built {{cljs.jar}} is built via {{script/uberjar}} and is expected to be found under {{target}} dir.
- CI server built maven jars are deployed via {{script/build}}
Manual testing
- Apply patch of this work to fresh clone of clojurescript
- On MacOS Mojave, from project root, go through cljs community build and test guides while also glancing at {{.travis.yml}}, namely:
script/build
lein test
./script/bootstrap
./script/test
./script/test-self-host
./script/test-self-parity
./script/uberjar
./script/test-cli browser
./script/test-cli node
./script/test-cli nashorn
./script/test-cli rhino
(export PATH="$GRAALVM_HOME:$PATH"; ./script/test-cli graaljs)
git status
- Verify that {{git status}} reports no modifications
- Compare output from above against cljs sources without this patch.
- Compare {{cljs.jar}} and maven deployed jars against cljs jars without this patch.
- Repeat the above for linux using a docker image based on {{circleci/clojure:openjdk-8-tools-deps-node}} skipping {{./script/test-cli browser}} step.
- {{script/aot_core}} references MinGW which I see was added in CLSJ-1797 to support running under "Git Bash" on Windows. I'll look into testing under that environment as well. Related: CLJS-3098.
Needs further verification by CI team
- CI specific code that is conditionally run when {{HUDSON}} is true in {{script/aot_core}} and {{script/build}}
- When does {{script/closure-library-release}} come into play? Note that I made no changes here.