Skip to content

Commit

Permalink
Fix package manager detection in non-monorepos (#907)
Browse files Browse the repository at this point in the history
  • Loading branch information
askoufis committed Nov 27, 2023
1 parent 5a3a780 commit 76ccc69
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/short-schools-report.md
@@ -0,0 +1,5 @@
---
'sku': patch
---

Fix package manager detection in non-monorepos
16 changes: 9 additions & 7 deletions packages/sku/config/lintStaged/lintStagedConfig.js
Expand Up @@ -2,16 +2,18 @@ const { isYarn } = require('../../lib/packageManager');
const { lintExtensions } = require('../../lib/lint');
const { getCommand } = require('@antfu/ni');

const steps = {};
/**
* @type {import('lint-staged').Config}
*/
const config = {
[`**/*.{${lintExtensions},md,less}`]: ['sku format', 'sku lint'],
};

// Yarn lock integrity check
if (isYarn) {
steps['+(package.json|yarn.lock)'] = [
() => getCommand('yarn', 'install', ['--check-files']),
config['+(package.json|yarn.lock)'] = [
getCommand('yarn', 'install', ['--check-files']),
];
}

// Format & lint
steps[`**/*.{${lintExtensions},md,less}`] = ['sku format', 'sku lint'];

module.exports = steps;
module.exports = config;
39 changes: 32 additions & 7 deletions packages/sku/lib/packageManager.js
@@ -1,6 +1,8 @@
const { existsSync } = require('node:fs');
const { join } = require('node:path');
const { cwd } = require('../lib/cwd');
const { findRootSync } = require('@manypkg/find-root');
const { getCommand, INSTALL_PAGE } = require('@antfu/ni');
const { getCommand, INSTALL_PAGE, LOCKS } = require('@antfu/ni');

const { sync: which } = require('which');
const skuArgs = require('../config/args');
Expand All @@ -10,6 +12,19 @@ const skuArgs = require('../config/args');
/** @type {Array<SupportedPackageManager>} */
const supportedPackageManagers = ['yarn', 'pnpm', 'npm'];

/** @type {Record<SupportedPackageManager, string>} */
const lockfileForPackageManager = Object.fromEntries(
Object.entries(LOCKS)
.filter(([, packageManager]) =>
supportedPackageManagers.includes(packageManager),
)
.map(([lockfileName, packageManager]) => [packageManager, lockfileName]),
);

const supportedLockfiles = supportedPackageManagers.map(
(packageManager) => lockfileForPackageManager[packageManager],
);

/**
* @param {SupportedPackageManager} commandName
* @returns {SupportedPackageManager | null}
Expand All @@ -24,18 +39,28 @@ const detectPackageManager = () =>

/**
* Get the package manager and root directory of the project. If the project does not have a
* project manager configured, a supported package manager will be detected in your `PATH`, and
* package manager configured, a supported package manager will be detected in your `PATH`, and
* `rootDir` will be `null`.
* @returns {{packageManager: SupportedPackageManager, rootDir: string | null}}
*/
const getPackageManager = () => {
let _packageManager = skuArgs?.packageManager;

// @manypkg/find-root only returns a tool if it finds a monorepo.
// If it finds a regular repo, it will return a 'root' tool, which is absolutely useless.
// So we need to detect the package manager ourselves. I'd use `detect` from from `@antfu/ni` or
// `detect-package-manager`, but they're async only and we can't make getPackageManager async.
try {
const {
tool: { type: foundPackageManager },
rootDir,
} = findRootSync(cwd());
const { rootDir } = findRootSync(cwd());

let foundPackageManager;

for (const supportedLockfile of supportedLockfiles) {
if (existsSync(join(rootDir, supportedLockfile))) {
foundPackageManager = LOCKS[supportedLockfile];
break;
}
}

if (!supportedPackageManagers.includes(foundPackageManager)) {
throw new Error('Unsupported package manager found');
Expand Down Expand Up @@ -126,7 +151,7 @@ const getAddCommand = ({ type, logLevel, deps, exact }) => {
return getCommand(packageManager, 'add', args);
};

const getInstallCommand = () => getCommand(packageManager, 'install', []);
const getInstallCommand = () => getCommand(packageManager, 'install');

const getWhyCommand = () => {
const whyCommand = isPnpm ? 'why -r' : 'why';
Expand Down
5 changes: 3 additions & 2 deletions packages/sku/lib/preCommit.js
@@ -1,11 +1,12 @@
const chalk = require('chalk');

const config = require('../config/lintStaged/lintStagedConfig');
const lintStaged = require('lint-staged');
const configPath = require.resolve('../config/lintStaged/lintStagedConfig');

module.exports = async () => {
let success = false;
try {
success = await lintStaged({ configPath });
success = await lintStaged({ config });
} catch (e) {
console.error(chalk.red(e));
}
Expand Down

0 comments on commit 76ccc69

Please sign in to comment.