-
Notifications
You must be signed in to change notification settings - Fork 30
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
Alternative build method #420
Conversation
Forgot to mention: I want comments if people think this is a move in the right direction. If you think so, I'll work to fix the issues I mentioned on this PR :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the approach to modernizing the build script. 👍🏻
However, I am not sure if this covers all the things that the current build script does. So it needs some close comparison and verification.
Some things don't match how we have been working in the organization. For example, we have been trying to use pnpm
instead of apm
for years. So, this should change yarn
back to apm/npm
(since the pnpm conversion is happening on other branches).
Should we decide to go through this route, we have to decide if we're going to keep the idea of using "V8 snapshots" to load Atom faster, and if we want to transpile code.
We definitely need to keep the V8 snapshots. The performance difference is like night and day. We also need to keep transpilation as many projects rely on this.
Once this is ready, we should probably remove the old method. We don't want to maintain two parallel ways to build Atom.
Good, so I'll keep working on it. What I know is that it currently is not making any transpilation and it's not generating the V8 snapshots, so I'll try to make these work and update this PR :) |
Honestly, I don't want to keep using yarn - if possible, I would like to mibrate to |
I changed the priority to low as it is not urgent. |
Notes on the things that aren't working:
That is currently handled by script/lib/transpile-packages-with-custom-transpiler-paths.js See also upstream's version of the same file: https://github.com/atom/atom/blob/master/script/lib/transpile-packages-with-custom-transpiler-paths.js)
Well, normally atom is run from a shell script on Unix-like OSes. The shell script hands off to the real
The snapshots are giving us relatively a lot of trouble whenever we try to change things. Meanwhile, I can't really tell what difference it makes. I tried removing Take a look at upstream's PR and reasons for introducing snapshots: atom#13916 The PRs that introduced the snapshot way back when contemplated speedups of ~200-300 milliseconds on loading a new editor, maybe around a second or two if loading an editor window with lots of packages to initialize. That's not much faster in my opinion, in order to deal with all this hassle of snapshotting. It's a nice idea, but causes so many headaches. We don't have the dev power upstream had at the time when they committed to snapshots. HOWEVER: We can try excluding problematic paths from the snapshot script, rather than deleting the snapshot altogether... https://github.com/atom/atom/blob/v1.60.0/script/lib/generate-startup-snapshot.js#L31-L262
Probably because the relative path to apm is changed on this branch. I think if you installed with |
@DeeDeeG using |
"devDependencies": { | ||
"electron": "11.5.0", | ||
"electron-builder": "^23.1.0", | ||
"electron-rebuild": "^3.2.7" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are going to break the snapshot script. They should be moved to script/package.json
"build": "electron-rebuild", | ||
"build:apm": "cd apm; yarn install; ./node_modules/atom-package-manager/bin/npm rebuild", | ||
"start": "electron .", | ||
"dist": "node script/electron-builder.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather see the electron-builder as a part of the current build process. Then, the duplicate parts of the current build can be removed. See #311 for an example to run this. I did it for Parcel before generating the snapshots.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually made this experiment to see if we could replace the current build process, as it seems completely unreliable. But I also see your point. Maybe we can discuss this here? #443
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added my response here:
#443 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more comments in case we get back to this. But do not spend a lot of time on it for now.
@@ -0,0 +1,104 @@ | |||
const path = require('path') | |||
const normalizePackageData = require('normalize-package-data'); | |||
const fs = require("fs/promises"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fs/promises
is only available on newer Node versions.
}) | ||
} | ||
|
||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the promises should be handled.
main() | |
main().catch((err) => { | |
throw err; | |
} |
builder.build({ | ||
config: options | ||
}).then((result) => { | ||
console.log("Built binaries") | ||
fs.mkdir('binaries').catch(() => "") | ||
Promise.all(result.map(r => fs.copyFile(r, path.join('binaries', path.basename(r))))) | ||
}).catch((error) => { | ||
console.error("Error building binaries") | ||
console.error(error) | ||
process.exit(1) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use async/await
and try/catch
config: options | ||
}).then((result) => { | ||
console.log("Built binaries") | ||
fs.mkdir('binaries').catch(() => "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you ignore the error?
}).then((result) => { | ||
console.log("Built binaries") | ||
fs.mkdir('binaries').catch(() => "") | ||
Promise.all(result.map(r => fs.copyFile(r, path.join('binaries', path.basename(r))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the promises should be handled.
Promise.all(result.map(r => fs.copyFile(r, path.join('binaries', path.basename(r))))) | |
await Promise.all(result.map(r => fs.copyFile(r, path.join('binaries', path.basename(r))))) |
function buildBundledPackagesMetadata(packageJSON) { | ||
const packages = {}; | ||
for (let packageName of Object.keys(packageJSON.packageDependencies)) { | ||
const packagePath = path.join('node_modules', packageName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use CONFIG to get the absolute path of node_modules
const packageMenusPath = path.join(packagePath, 'menus'); | ||
if (fs.existsSync(packageMenusPath)) { | ||
for (let packageMenuName of fs.readdirSync(packageMenusPath)) { | ||
const packageMenuPath = path.join(packageMenusPath, packageMenuName); | ||
if ( | ||
packageMenuPath.endsWith('.cson') || | ||
packageMenuPath.endsWith('.json') | ||
) { | ||
packageNewMetadata.menus[packageMenuPath] = CSON.readFileSync( | ||
packageMenuPath | ||
); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each of these blocks of code can become a function with a descriptive name and good documentation.
@@ -1,5 +1,6 @@ | |||
{ | |||
"name": "atom", | |||
"author": "Atom Community <[email protected]>", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct email is [email protected]
@@ -161,7 +161,7 @@ | |||
"temp": "0.9.2", | |||
"text-buffer": "^13.18.5", | |||
"timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball", | |||
"tree-sitter": "git+https://github.com/DeeDeeG/node-tree-sitter.git#bb298eaae66e0c4f11908cb6209f3e141884e88e", | |||
"tree-sitter": "^0.17.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be a different pull request
@@ -69,7 +70,6 @@ | |||
"fuzzy-finder": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.14.3/tarball", | |||
"git-diff": "file:packages/git-diff", | |||
"git-utils": "5.7.1", | |||
"github": "https://www.atom.io/api/packages/github/versions/0.36.10/tarball", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you remove GitHub from Atom?
Ok, so this PR was to try an alternative build method that did not depend on scripts at all (or the least we can). The way it's currently moving, and considering priorities, this is probably add another moving piece to what is somewhat too many moving pieces, so I'll close this PR. We may re-organize ideas in the future, when higher priorities are attended. Also, to handle the new requirements of using electron-builder over the transpiled version of packages and everything, this PR will need to change quite a lot; finally, as we're now, I'm monkey-patching Electron Builder to not remove some metadata that we actually need, so again, I'm not sure this is useful right now. So, closing for now as to not clutter the PRs we actually need to attend, we may re-visit this in the future. |
Please keep it open so it is not lost |
I decided to draft this PR to request for comments (I think "code' speaks better than words in this case). So, this PR fundamentally changes how we create Atom binaries.
Motivation
Currently, Atom builds binaries with a combination of
./script/bootstrap
and./script/build
. I could not run./script/boostrap
in a reliable way, and discussing with some people it seems that it does not function with recentnpm
versions. Also, all the scripts to build Atom end up adding more than 5.000 lines of code that the community will have to both understand and maintain, so I decided to make a quick spike to see how hard it would be to build Atom without these scriptsHow is being done?
I'm using
yarn
instead ofnpm
and I'm addingelectron-builder
, Electron and some other packages todev-dependencies
for easier bootrapping of the app. I also updated a doc to show how to start developing Atom with this method.What is not working?
Unfortunately, this method is not 100% complete yet. Atom works, but
github
package is developed with ESM modules, so it can't be loaded as of now (probably the boostrap script ends up usingbabel
to transpile code). Other packages work, but another problem is that "core" packages are missing their README files for some reason. So the list of things I know we'll have to take a look:-f
switchapm
does not get installed on the PATH - this may need to be fixedWhat is the advantage?
Updating some "core" packages like Electron and Tree-Sitter currently is very hard. Atom solution is to "boostrap" and then point an existing Atom editor to the "bootstrapped" package, which is not that reliable and also does not help on the Electron case. Also, it's all made with custom scripts, which are not reliable as they are now. We may fix the scripts to work 100% of the time, but IMHO it's better to embrace what the Node/JS/Electron community is using so we gain bugfixes and access to more targets when they appear.
Also, the current package is able to auto-update an
AppImage
on Linux if we decide to implement this (electron-builder
have a way to implement a cross-platform independent auto-updater). It is also able to draft releases on GitHub too, and the number of lines of code that I had to write to make it work is really small compared with the scripts directory.Should we decide to go through this route, we have to decide if we're going to keep the idea of using "V8 snapshots" to load Atom faster, and if we want to transpile code. Also, maybe it's a good idea to, in the future, change the way Atom detects "core" packages - currently, it's somewhat weird and depends on adding stuff on
package.json
. Maybe a better way could be to just make Atom search for packages in two directories - theATOM_HOME
and the "asar" file when bundled.