Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix package manager detection in non-monorepos #907

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/short-schools-report.md
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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