From b8e453ec5684480c7937084402365982fa40e55e Mon Sep 17 00:00:00 2001 From: killa Date: Wed, 25 Oct 2023 19:20:30 +0800 Subject: [PATCH] feat: auto install fuse-t (#40) * feat: auto install fuse-t * feat: add INSTALL_FUSE_T env --- .github/workflows/ci.yml | 7 +------ README.md | 3 +++ packages/cli/bin/rapid.js | 6 ++++++ packages/cli/lib/fuse_t.js | 42 ++++++++++++++++++++++++++++++++++++++ packages/cli/lib/util.js | 6 +++--- packages/cli/package.json | 3 ++- 6 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 packages/cli/lib/fuse_t.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e2b011..aa86ff3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -181,11 +181,6 @@ jobs: - name: Change directory ownership run: chown -R $(id -un):$(id -gn) . - - name: Install macfuse - run: | - wget https://github.com/macos-fuse-t/fuse-t/releases/download/1.0.24/fuse-t-macos-installer-1.0.24.pkg - sudo installer -pkg fuse-t-macos-installer-1.0.24.pkg -target / - - name: Rust Cache uses: actions/cache@v3 with: @@ -205,6 +200,6 @@ jobs: CARGO_BUILD_TARGET=x86_64-apple-darwin BUILD_OS=macos BUILD_ARCH=amd64 npm run init:ci - name: Run CI - run: npm run test:integration + run: INSTALL_FUSE_T=true npm run test:integration env: NODE_OPTIONS: --max_old_space_size=6144 diff --git a/README.md b/README.md index eee8034..3f8d9d6 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ The fastest way to install npm packages. const rapid = require('@cnpmjs/rapid'); await rapid({}); ``` + +# 🎁 Acknowledgements +- [fuse-t](https://github.com/macos-fuse-t/fuse-t) Thanks fuse-t for kext-less implementation of FUSE. diff --git a/packages/cli/bin/rapid.js b/packages/cli/bin/rapid.js index ef2748c..5721a6d 100755 --- a/packages/cli/bin/rapid.js +++ b/packages/cli/bin/rapid.js @@ -7,6 +7,7 @@ const yargs = require('yargs'); const { NpmFsMode, NYDUS_TYPE } = require('../lib/constants.js'); const util = require('../lib/util'); const path = require('node:path'); +const fuse_t = require('../lib/fuse_t'); yargs .command({ @@ -31,6 +32,11 @@ yargs const cwd = process.cwd(); const pkgRes = await util.readPkgJSON(); const pkg = pkgRes?.pkg || {}; + if (!(await fuse_t.checkFuseT())) { + if (await fuse_t.confirmInstallFuseT()) { + await fuse_t.installFuseT(); + } + } await util.shouldFuseSupport(); await install({ diff --git a/packages/cli/lib/fuse_t.js b/packages/cli/lib/fuse_t.js new file mode 100644 index 0000000..1969ae3 --- /dev/null +++ b/packages/cli/lib/fuse_t.js @@ -0,0 +1,42 @@ +const fs = require('node:fs/promises'); +const fsSync = require('node:fs'); +const crypto = require('node:crypto'); +const path = require('node:path'); +const urllib = require('urllib'); +const execa = require('execa'); +const inquirer = require('inquirer'); + +const FUSE_T_INSTALL_PATH = '/usr/local/bin/go-nfsv4'; +const FUSE_T_VERSION = '1.0.28'; +const FUSE_T_DOWNLOAD_URL = `https://registry.npmmirror.com/-/binary/fuse-t/${FUSE_T_VERSION}/fuse-t-macos-installer-${FUSE_T_VERSION}.pkg`; + +exports.checkFuseT = async function checkFuseT() { + try { + await fs.stat(FUSE_T_INSTALL_PATH); + return true; + } catch { + return false; + } +}; + +exports.installFuseT = async function installFuseT() { + const tmpPath = path.join('/tmp', `${crypto.randomUUID()}.pkg`); + await urllib.request(FUSE_T_DOWNLOAD_URL, { + method: 'GET', + writeStream: fsSync.createWriteStream(tmpPath), + followRedirect: true, + }); + await execa.command(`sudo installer -pkg ${tmpPath} -target /`); +}; + +exports.confirmInstallFuseT = async function confirmInstallFuseT() { + if (process.env.INSTALL_FUSE_T === 'true') return true; + if (!process.stdout.isTTY) return false; + const answers = await inquirer.prompt([{ + type: 'confirm', + name: 'installFuseT', + message: 'Do you want install fuse-t?', + default: true, + }]); + return answers.installFuseT === true; +}; diff --git a/packages/cli/lib/util.js b/packages/cli/lib/util.js index fe499af..c88586e 100644 --- a/packages/cli/lib/util.js +++ b/packages/cli/lib/util.js @@ -8,6 +8,7 @@ const os = require('node:os'); const url = require('node:url'); const crypto = require('node:crypto'); const mapWorkspaces = require('@npmcli/map-workspaces'); +const fuse_t = require('./fuse_t'); const parser = require('yargs-parser'); const { NpmFsMode } = require('./constants'); @@ -103,9 +104,8 @@ async function shouldFuseSupport() { } if (os.type() === 'Darwin') { - try { - await fs.stat('/usr/local/bin/go-nfsv4'); - } catch (error) { + const fuseTInstalled = await fuse_t.checkFuseT(); + if (!fuseTInstalled) { throw new NotSupportedError('install fuse-t first.'); } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 43d26e9..36f455c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -27,7 +27,8 @@ "semver": "^7.3.8", "urllib": "^3.16.1", "yargs": "^17.7.2", - "yargs-parser": "^9.0.2" + "yargs-parser": "^9.0.2", + "inquirer": "^8.2.6" }, "homepage": "https://github.com/cnpm/rapid", "repository": {