Skip to content

Commit

Permalink
refactor(cli): binary install (#990)
Browse files Browse the repository at this point in the history
  • Loading branch information
QuiiBz authored Jun 25, 2023
1 parent dd96fd0 commit 987642d
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 77 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-waves-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lagon/cli': patch
---

Refactor binary installation to be more stable
119 changes: 119 additions & 0 deletions crates/cli/npm/binary-install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// All credit goes to Cloudflare wrangler-legacy and
// the initial binary-install package, which this code
// is heavily based on.
//
// Cloudflare wrangler-legacy: https://github.com/cloudflare/wrangler-legacy/blob/master/npm/binary-install.js
// binary-install: https://github.com/EverlastingBugstopper/binary-install#readme
import { existsSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
import { spawnSync } from 'node:child_process';

import axios from 'axios';
import tar from 'tar';
import { rimraf } from 'rimraf';

const error = msg => {
console.error(msg);
process.exit(1);
};

export class Binary {
constructor(url, data) {
this.url = url;
this.name = data.name || -1;
this.installDirectory = data.installDirectory;
this.binaryDirectory = -1;
this.binaryPath = -1;
}

_getInstallDirectory() {
if (!existsSync(this.installDirectory)) {
mkdirSync(this.installDirectory, { recursive: true });
}
return this.installDirectory;
}

_getBinaryDirectory() {
const installDirectory = this._getInstallDirectory();
const binaryDirectory = join(installDirectory, 'bin');
if (existsSync(binaryDirectory)) {
this.binaryDirectory = binaryDirectory;
} else {
error(`You have not installed ${this.name}`);
}
return this.binaryDirectory;
}

_getBinaryPath() {
if (this.binaryPath === -1) {
const binaryDirectory = this._getBinaryDirectory();
this.binaryPath = join(binaryDirectory, this.name);
}

return this.binaryPath;
}

install() {
const dir = this._getInstallDirectory();
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}

this.binaryDirectory = join(dir, 'bin');

if (existsSync(this.binaryDirectory)) {
rimraf.sync(this.binaryDirectory);
}

mkdirSync(this.binaryDirectory, { recursive: true });

console.log(`Downloading release from ${this.url}`);

return axios({ url: this.url, responseType: 'stream' })
.then(res => {
const writer = tar.x({ strip: 1, C: this.binaryDirectory });

return new Promise((resolve, reject) => {
res.data.pipe(writer);
let error = null;
writer.on('error', err => {
error = err;
reject(err);
});
writer.on('close', () => {
if (!error) {
resolve(true);
}
});
});
})
.then(() => {
console.log(`${this.name} has been installed!`);
})
.catch(e => {
error(`Error fetching release: ${e.message}`);
});
}

uninstall() {
if (existsSync(this._getInstallDirectory())) {
rimraf.sync(this.installDirectory);
console.log(`${this.name} has been uninstalled`);
}
}

run() {
const binaryPath = this._getBinaryPath();
const [, , ...args] = process.argv;

const options = { cwd: process.cwd(), stdio: 'inherit' };

const result = spawnSync(binaryPath, args, options);

if (result.error) {
error(result.error);
}

process.exit(result.status);
}
}
6 changes: 4 additions & 2 deletions crates/cli/npm/getBinary.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createRequire } from 'node:module';
import { Binary } from 'binary-install';
import { Binary } from './binary-install.js';
import os from 'node:os';
import path from 'node:path';

function getPlatform() {
const type = os.type();
Expand Down Expand Up @@ -51,6 +52,7 @@ export function getBinary() {
const { name: packageName, version } = customRequire('../package.json');

const url = `https://github.com/lagonapp/lagon/releases/download/${packageName}@${version}/${platform}.tar.gz`;
const installDirectory = path.join(os.homedir(), '.lagon');

return new Binary(name, url);
return new Binary(url, { name, installDirectory });
}
12 changes: 4 additions & 8 deletions crates/cli/npm/install.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#!/usr/bin/env node

// Prevent exiting with code 1
// Prevent exiting with code 1 when
// the changeset PR is created
process.exit = () => {};

try {
import('./getBinary.js').then(({ getBinary }) => {
getBinary().install();
});
} catch (error) {
console.error(error);
}
import { getBinary } from './getBinary.js';
getBinary().install();
5 changes: 1 addition & 4 deletions crates/cli/npm/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,4 @@ const pkg = customRequire('../package.json');

updateNotifier({ pkg }).notify();

const binary = getBinary();

// Try to install the binary before executing the CLI
binary.install({}, true).then(() => binary.run());
getBinary().run();
4 changes: 3 additions & 1 deletion crates/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"postinstall": "node npm/install.js"
},
"dependencies": {
"binary-install": "^1.0.6",
"axios": "^1.4.0",
"rimraf": "^5.0.1",
"tar": "^6.1.15",
"update-notifier": "^6.0.2"
},
"devDependencies": {
Expand Down
Loading

4 comments on commit 987642d

@vercel
Copy link

@vercel vercel bot commented on 987642d Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./packages/docs

docs-lagon.vercel.app
lagon-docs.vercel.app
docs-git-main-lagon.vercel.app
docs.lagon.app

@vercel
Copy link

@vercel vercel bot commented on 987642d Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

storybook – ./packages/ui

storybook-swart-eight.vercel.app
storybook-git-main-lagon.vercel.app
storybook-lagon.vercel.app
ui.lagon.app

@vercel
Copy link

@vercel vercel bot commented on 987642d Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

www – ./www

www-git-main-lagon.vercel.app
lagon.app
www-lagon.vercel.app
lagon.dev

@vercel
Copy link

@vercel vercel bot commented on 987642d Jun 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

dashboard – ./packages/dashboard

dashboard-git-main-lagon.vercel.app
dash.lagon.app
dashboard-lagon.vercel.app

Please sign in to comment.