Skip to content

Commit

Permalink
Add Yarn PnP support
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmeuli committed Feb 12, 2020
1 parent 94736bb commit b0399df
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 16 deletions.
8 changes: 4 additions & 4 deletions src/linters/eslint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const commandExists = require("../../vendor/command-exists");
const { run } = require("../utils/action");
const { initLintResult } = require("../utils/lint-result");
const { runNpmBin } = require("../utils/npm");
const { removeTrailingPeriod } = require("../utils/string");

/**
Expand All @@ -23,7 +23,7 @@ class ESLint {

// Verify that ESLint is installed
try {
run("npx --no-install eslint -v", { dir });
runNpmBin("eslint -v", { dir });
} catch (err) {
throw new Error(`${this.name} is not installed`);
}
Expand All @@ -40,8 +40,8 @@ class ESLint {
static lint(dir, extensions, args = "", fix = false) {
const extensionsArg = extensions.map(ext => `.${ext}`).join(",");
const fixArg = fix ? "--fix" : "";
return run(
`npx --no-install eslint --ext ${extensionsArg} ${fixArg} --no-color --format json ${args} "."`,
return runNpmBin(
`eslint --ext ${extensionsArg} ${fixArg} --no-color --format json ${args} "."`,
{
dir,
ignoreErrors: true,
Expand Down
6 changes: 3 additions & 3 deletions src/linters/prettier.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const commandExists = require("../../vendor/command-exists");
const { run } = require("../utils/action");
const { initLintResult } = require("../utils/lint-result");
const { runNpmBin } = require("../utils/npm");

/**
* https://prettier.io
Expand All @@ -22,7 +22,7 @@ class Prettier {

// Verify that Prettier is installed
try {
run("npx --no-install prettier -v", { dir });
runNpmBin("prettier -v", { dir });
} catch (err) {
throw new Error(`${this.name} is not installed`);
}
Expand All @@ -40,7 +40,7 @@ class Prettier {
const files =
extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
const fixArg = fix ? "--write" : "--list-different";
return run(`npx --no-install prettier ${fixArg} --no-color ${args} "${files}"`, {
return runNpmBin(`prettier ${fixArg} --no-color ${args} "${files}"`, {
dir,
ignoreErrors: true,
});
Expand Down
15 changes: 6 additions & 9 deletions src/linters/stylelint.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const commandExists = require("../../vendor/command-exists");
const { run } = require("../utils/action");
const { initLintResult } = require("../utils/lint-result");
const { runNpmBin } = require("../utils/npm");

/**
* https://stylelint.io
Expand All @@ -22,7 +22,7 @@ class Stylelint {

// Verify that stylelint is installed
try {
run("npx --no-install stylelint -v", { dir });
runNpmBin("stylelint -v", { dir });
} catch (err) {
throw new Error(`${this.name} is not installed`);
}
Expand All @@ -40,13 +40,10 @@ class Stylelint {
const files =
extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
const fixArg = fix ? "--fix" : "";
return run(
`npx --no-install stylelint --no-color --formatter json ${fixArg} ${args} "${files}"`,
{
dir,
ignoreErrors: true,
},
);
return runNpmBin(`stylelint --no-color --formatter json ${fixArg} ${args} "${files}"`, {
dir,
ignoreErrors: true,
});
}

/**
Expand Down
33 changes: 33 additions & 0 deletions src/utils/npm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { existsSync } = require("fs");
const { join } = require("path");

const { run } = require("../utils/action");

const YARN_LOCK_NAME = "yarn.lock";

/**
* Determines whether Yarn should be used to execute commands or binaries. This decision is based on
* the existence of a Yarn lockfile in the package directory. The distinction between NPM and Yarn
* is necessary e.g. for Yarn Plug'n'Play to work
* @param {string} [pkgRoot] - Package directory (directory where Yarn lockfile would exist)
* @returns {boolean} - Whether Yarn should be used
*/
function useYarn(pkgRoot) {
// Use an absolute path if `pkgRoot` is specified and a relative one (current directory) otherwise
const lockfilePath = pkgRoot ? join(pkgRoot, YARN_LOCK_NAME) : YARN_LOCK_NAME;
return existsSync(lockfilePath);
}

/**
* Executes the specified binary with NPM or Yarn (the correct tool is determined automatically).
* This function wraps the general {@see run} function and accepts the same parameters
* @param {string} cmd - NPM binary to execute
* @param {{dir: string, ignoreErrors: boolean}} [options] - {@see RUN_OPTIONS_DEFAULTS}
* @returns {{status: number, stdout: string, stderr: string}} - Output of the NPM binary
*/
function runNpmBin(cmd, options) {
const npmCmd = useYarn(options.dir) ? `yarn run --silent ${cmd}` : `npx --no-install ${cmd}`;
return run(npmCmd, options);
}

module.exports = { runNpmBin };

0 comments on commit b0399df

Please sign in to comment.