Skip to content

Commit

Permalink
Merge pull request #268 from nodists/fix-installer-versions
Browse files Browse the repository at this point in the history
fix(build): use known working node version for the installer
  • Loading branch information
nullivex authored Dec 7, 2023
2 parents e4e67cd + 8b5373a commit 3d7483c
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 766 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch:


jobs:
run-build:
Expand All @@ -23,7 +25,14 @@ jobs:
run: Copy-Item (Get-Command node.exe | Select-Object -ExpandProperty Definition) .
- run: npm test
- run: npm run build
- name: Archive build artifact
if: github.ref_type == 'branch'
uses: actions/upload-artifact@v3
with:
name: Installer
path: "build/out/NodistSetup-*.exe"
- name: Create release draft
if: github.ref_type == 'tag'
uses: ncipollo/release-action@v1
with:
artifacts: "build/out/NodistSetup-*.exe"
Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
name: run-tests

on:
push:
branches:
- '**'
tags-ignore:
- '**'
pull_request:

jobs:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ MIT License

## Changelog

v0.10.1
v0.10.2
* Fix building shims (for newer go versions) by using go modules
* Fix npm shim to use correct node version
* Add npx shim (works only for npm versions that ship with npx)
* Fix getting latest npm version
* Use last available x86 version for building (first node 18 versions are not available for x86)
Expand Down
46 changes: 13 additions & 33 deletions build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var fs = require('fs');
var mkdirp = require('mkdirp');
var ncp = require('ncp');
var path = require('path');
var semver = require('semver');
var recursiveReaddir = require('recursive-readdir');
var request = require('request');
var rimraf = require('rimraf');
Expand Down Expand Up @@ -83,6 +84,7 @@ var npm = new (require('../lib/npm'))({nodistDir: stagingDir});
//default npm version to the latest at the time of writing
var npmVersion = '6.14.16';
var nodeVersion = '16.15.0';
var maxNodeMainVersion = '^20';

var versionPathx86 = '';
var versionPathx64 = '';
Expand All @@ -102,31 +104,14 @@ console.log('Welcome to the Nodist Builder');
console.log(' before going further we need to prep our staging folder');

//defining helper functions
function getLatestNodeVersionFor(nodeVersions, fileType) {
function getLatestUsableNodeVersionFor(nodeVersions, fileType) {
for (var key in nodeVersions) {
if (nodeVersions[key].files.includes(fileType)) {
return nodeVersions[key].version;
if (nodeVersions[key].files.includes(fileType) && semver.satisfies(nodeVersions[key].version, maxNodeMainVersion)) {
return { nodeVersion: nodeVersions[key].version, npmVersion: nodeVersions[key].npm };
}
}
}

async function resolveLinkedWorkspaces(dirPath) {
let movedLinks = 0;
const files = await fs.readdirAsync(dirPath, { withFileTypes: true });
const dirPromises = [];
for (const file of files) {
const filePath = path.join(dirPath, file.name);
if (file.isSymbolicLink()) {
const linkTarget = await fs.readlinkAsync(filePath);
await fs.renameAsync(path.join(dirPath, linkTarget), filePath);
movedLinks++;
} else if (file.isDirectory()) {
dirPromises.push(resolveLinkedWorkspaces(filePath));
}
}
return (await Promise.all(dirPromises)).reduce((sum, num) => sum + num, movedLinks);
}

//start by clearing the staging and tmp folders
P.all([
rimraf(outDir),
Expand Down Expand Up @@ -193,19 +178,19 @@ P.all([
console.log('Finished copying static files');

console.log('Compiling node shim');
return exec('go build -o "'+stagingBin +'/node.exe" shim-node.go', { cwd: goSrcDir });
return exec('go build -o "'+stagingBin +'/node.exe" ./cmd/node', { cwd: goSrcDir });
})
.then(function(){
console.log('Done compiling node shim');

console.log('Compiling npm shim');
return exec('go build -o "'+stagingBin +'/npm.exe" shim-npm.go', { cwd: goSrcDir });
return exec('go build -o "'+stagingBin +'/npm.exe" ./cmd/npm', { cwd: goSrcDir });
})
.then(function(){
console.log('Done compiling npm shim');

console.log('Compiling npx shim');
return exec('go build -o "'+stagingBin +'/npx.exe" shim-npx.go', { cwd: goSrcDir });
return exec('go build -o "'+stagingBin +'/npx.exe" ./cmd/npx', { cwd: goSrcDir });
})
.then(function() {
console.log('Done compiling npx shim');
Expand All @@ -217,7 +202,7 @@ P.all([
});
})
.then(function(res){
nodeVersion = getLatestNodeVersionFor(res.body, 'win-x86-exe');
({ nodeVersion, npmVersion } = getLatestUsableNodeVersionFor(res.body, 'win-x86-exe'));
nodeLatestUrlx86 = nodeLatestUrlx86.replace('VERSION',nodeVersion);
nodeLatestUrlx64 = nodeLatestUrlx64.replace('VERSION',nodeVersion);
console.log('Latest version of Node ' + nodeVersion);
Expand Down Expand Up @@ -253,14 +238,9 @@ P.all([
);
})
.then(function(){
console.log('Figure out the latest version of NPM');
return npm.latestVersion();
})
.then(function(version){
npmVersion = version;
var downloadLink = npm.downloadUrl(version);
console.log('Determined latest NPM as ' + npmVersion);
console.log('Downloading latest NPM from ' + downloadLink);
var downloadLink = npm.downloadUrl(npmVersion);
console.log('Determined matching NPM as ' + npmVersion);
console.log('Downloading matching NPM from ' + downloadLink);
return Promise.resolve()
.then(() => mkdirp(stagingNpmDir+'/'+npmVersion.replace('v','')))
.then(() => {
Expand Down Expand Up @@ -291,7 +271,7 @@ P.all([
})
.then(function() {
console.log('Installation complete');
return resolveLinkedWorkspaces(path.join(stagingNpmDir, npmVersion.replace('v', ''), 'node_modules'));
return helper.resolveLinkedWorkspaces(path.join(stagingNpmDir, npmVersion.replace('v', '')), false);
})
.then(function(movedLinks) {
if (movedLinks) {
Expand Down
52 changes: 52 additions & 0 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ var path = require('path');
var promisePipe = require('promisepipe');
var ProgressBar = require('progress');
var request = require('request');
const P = require('bluebird');
var debug = require('debug')('nodist:build')

//make some promising APIs
P.promisifyAll(fs);

/**
* Copy File
* @param {string} source
Expand Down Expand Up @@ -141,3 +145,51 @@ exports.downloadFileStream = function downloadFileStream(url) {
});
return req
}

/**
* Npm version >= 18 using symlinks that do not work in windows and have to be fixed
* this function replace the broken symlinks with NTFS junction or move the directory if junctions are not supported
*
* @param {string} dirPath
* @param {boolean} preferSymlink
* @returns {Promise<number>} number of changed links
*/
exports.resolveLinkedWorkspaces = async function resolveLinkedWorkspaces(dirPath, preferSymlink = true) {
let fixedLinks = 0;
const packageLockJson = JSON.parse(fs.readFileSync(path.join(dirPath, 'package-lock.json')).toString());
await Promise.all(Object.entries(packageLockJson.packages)
.filter(([pkgPath, pkg]) => pkg.link === true)
.map(async ([pkgPath, pkg]) => {

const linkPath = path.join(dirPath, pkgPath);


if (await fs.accessAsync(linkPath, fs.constants.F_OK).then(() => true).catch(() => false)) {
await fs.unlinkAsync(linkPath);
}

let linkCreated = false;
if (preferSymlink) {
const linkTarget = path.join(
...pkgPath.split('/').slice(0, -1).map(() => '..'),
pkg.resolved
);
debug('Create symlink for ', linkPath, 'with target', linkTarget);
try {
await fs.symlinkAsync(linkTarget, linkPath, 'junction');
linkCreated = true;
} catch (e) {
debug('Link ', linkPath, 'could not be created');
}
}
if (!linkCreated) {
const from = path.join(dirPath, pkg.resolved);
debug('Move', from, 'to', linkPath);
await fs.renameAsync(from, linkPath);
}

fixedLinks++;
}));

return fixedLinks;
};
37 changes: 1 addition & 36 deletions lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,6 @@ module.exports = npmist

var NPMIST = npmist.prototype

/**
* Npm version >= 18 using symlinks that do not work in windows and have to be fixed
* this function replace the broken symlinks with NTFS junction or move the directory if junctions are not supported
*
* @param {string} dirPath
* @returns {Promise<number>} number of changed links
*/
async function resolveLinkedWorkspaces(dirPath) {
let fixedLinks = 0;
const packageLockJson = JSON.parse(fs.readFileSync(path.join(dirPath, 'package-lock.json')).toString());
await Promise.all(Object.entries(packageLockJson.packages)
.filter(([pkgPath, pkg]) => pkg.link === true)
.map(async ([pkgPath, pkg]) => {
const linkTarget = path.join(
...pkgPath.split('/').slice(0, -1).map(() => '..'),
pkg.resolved
);
const linkPath = path.join(dirPath, pkgPath);

debug('Create symlink for ', linkPath, 'with target', linkTarget);
if (await fs.accessAsync(linkPath, fs.constants.F_OK).then(() => true).catch(() => false)) {
await fs.unlinkAsync(linkPath);
}

try {
await fs.symlinkAsync(linkTarget, linkPath, 'junction');
} catch (e) {
await fs.renameAsync(path.join(dirPath, linkTarget), linkPath);
}
fixedLinks++;
}));

return fixedLinks;
}

/**
* List available NPM versions
* @return {string}
Expand Down Expand Up @@ -331,7 +296,7 @@ NPMIST.install = function(v,done){
.then(() => {
if (semver.gte(version, '8.0.0')) {
debug('Fix symlinks for npm version >= 8');
return resolveLinkedWorkspaces(path.join(archivePath))
return buildHelper.resolveLinkedWorkspaces(path.join(archivePath))
.then(fixedLinks => {
debug(`Fixed ${fixedLinks} symlinks for npm node_modules`);
});
Expand Down
16 changes: 16 additions & 0 deletions src/cmd/node/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import (
"os"
"os/exec"

nodist "github.com/nodists/nodist/internal"
)

func main() {
err, nodebin, _, _ := nodist.DetermineNodeExecutable("node")

// Run node!
cmd := exec.Command(nodebin, os.Args[1:]...)
nodist.ExecuteCommand(cmd, err)
}
23 changes: 23 additions & 0 deletions src/cmd/npm/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"os"
"os/exec"

nodist "github.com/nodists/nodist/internal"
)

func main() {
err, nodebin, dir, nodeVersion := nodist.DetermineNodeExecutable("node")

path, _ := nodist.DetermineNpmPath(dir, nodeVersion)

npmbin := path + "/bin/npm-cli.js"

args := []string{npmbin}
args = append(args, os.Args[1:]...)

// Run npm!
cmd := exec.Command(nodebin, args...)
nodist.ExecuteCommand(cmd, err)
}
30 changes: 30 additions & 0 deletions src/cmd/npx/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"errors"
"fmt"
"os"
"os/exec"

nodist "github.com/nodists/nodist/internal"
)

func main() {
err, nodebin, dir, nodeVersion := nodist.DetermineNodeExecutable("node")

path, npmVersion := nodist.DetermineNpmPath(dir, nodeVersion)

npxbin := path + "/bin/npx-cli.js"

if _, err := os.Stat(npxbin); errors.Is(err, os.ErrNotExist) {
fmt.Println("Npx not found for selected npm version:", npmVersion)
os.Exit(47)
}

args := []string{npxbin}
args = append(args, os.Args[1:]...)

// Run npx!
cmd := exec.Command(nodebin, args...)
nodist.ExecuteCommand(cmd, err)
}
2 changes: 1 addition & 1 deletion src/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/nodists/nodist

go 1.12
go 1.20

require (
github.com/marcelklehr/semver v0.0.0-20160716173943-4590ea5640ed // indirect
Expand Down
Loading

0 comments on commit 3d7483c

Please sign in to comment.