Skip to content

Commit 5bb376e

Browse files
authored
feat(cli): add support for other package managers (#749)
1 parent 83d4490 commit 5bb376e

38 files changed

Lines changed: 1279 additions & 595 deletions

.github/workflows/integration-tests.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
node-version: [20, 22, 24]
21+
package-manager: [npm, pnpm]
2122
steps:
2223
- name: Check out
2324
uses: actions/checkout@v6
@@ -26,15 +27,27 @@ jobs:
2627
uses: actions/setup-node@v6
2728
with:
2829
node-version: ${{ matrix.node-version }}
29-
cache: npm
30+
cache: "npm"
31+
32+
- name: Set up pnpm
33+
if: matrix.package-manager == 'pnpm'
34+
uses: pnpm/action-setup@v4
35+
with:
36+
version: 10
3037

3138
- name: Install dependencies
3239
run: npm ci
3340

34-
- name: Install create-next-app globally
41+
- name: Install create-next-app globally (npm)
42+
if: matrix.package-manager == 'npm'
3543
run: npx -y create-next-app@latest --version
3644

45+
- name: Install create-next-app globally (pnpm)
46+
if: matrix.package-manager == 'pnpm'
47+
run: pnpm dlx create-next-app@latest --version
48+
3749
- name: Run Vitest integration tests
3850
run: npm test
3951
env:
4052
NODE_VERSION: ${{ matrix.node-version }}
53+
PACKAGE_MANAGER: ${{ matrix.package-manager }}
File renamed without changes.

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ Aby użyć configu dodaj to pole w `package.json`:
5050
}
5151
```
5252

53-
## Eslint
53+
## ESLint
5454

55-
Wymagany jest `eslint` w wersji `9` lub nowszej oraz package.json powinien mieć pole
55+
Wymagany jest `eslint` w wersji `9` oraz package.json powinien mieć pole
5656

5757
```json
5858
{
@@ -103,3 +103,15 @@ Testy obejmują:
103103
- ✅ Weryfikację formatowania kodu
104104
- ✅ Build aplikacji Next.js
105105
- ✅ Testowanie warunków błędów
106+
107+
## Prawa autorskie
108+
109+
Copyright © 2024-2026 KN Solvro
110+
111+
Licencja: [MPL v2.0](./LICENSE.md)
112+
113+
Pierwotny twórca: [Bartosz Gotowski](https://github.com/Rei-x)
114+
115+
Utrzymuje: [Konrad Guzek](https://github.com/kguzek)
116+
117+
Stworzone na podstawie projektu [antfu/eslint-config](https://github.com/antfu/eslint-config), którego licencja dostępna jest w pliku [LICENSE2.md](./LICENSE2.md)

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
6767
"@eslint/config-helpers": "^0.4.2",
6868
"@eslint/js": "^9.37.0",
69+
"@solvro/utils": "^1.5.0",
6970
"@tanstack/eslint-plugin-query": "^5.91.4",
7071
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
7172
"@typescript-eslint/eslint-plugin": "^8.46.0",

src/cli/index.ts

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as p from "@clack/prompts";
22
import { Command } from "commander";
3-
import { getUserAgent } from "package-manager-detector/detect";
43
import c from "picocolors";
54

65
import packageJsonData from "../../package.json";
76
import { BUG_TRACKER_URL } from "../constants";
7+
import { checkIsNonInteractive } from "../utils/check-is-non-interactive";
88
import { confirmProjectType } from "../utils/confirm-project-type";
99
import { isGitClean } from "../utils/is-git-clean";
1010
import { PackageJson } from "../utils/package-json";
@@ -41,39 +41,17 @@ program
4141
program.parse();
4242
const options: CliOptions = program.opts();
4343

44-
// Check if running in non-interactive mode (any CLI flags provided)
45-
const isNonInteractive = process.argv.length > 2;
44+
const isNonInteractive = checkIsNonInteractive();
4645

4746
async function main() {
4847
if (!isNonInteractive) {
4948
p.intro(c.bold(c.bgBlue(" @solvro/config ")));
5049
}
5150

52-
const userAgent = getUserAgent();
53-
54-
if (userAgent !== "npm") {
55-
const packageManager = userAgent ?? "unknown";
56-
const warningMessage = `\
57-
${c.red(c.bold(`⚠️ OSTRZEŻENIE: ${packageManager} nie jest obsługiwany ⚠️`))}
58-
59-
Próbujesz uruchomić ten skrypt ${c.yellow(packageManager)}'em, ale @solvro/config obecnie działa tylko z ${c.green("npm")}'em.
60-
61-
${c.white(`Support dla innych menedżerów pakietów jest planowany w nadchodzących wersjach - ${c.yellow("zagwiazdkuj i spróbuj ponownie wkrótce")}!`)}
62-
63-
${c.white(`W międzyczasie użyj ${c.green("npm")}'a:`)}
64-
${c.cyan("npx @solvro/config")}`;
65-
66-
if (isNonInteractive) {
67-
console.error(warningMessage);
68-
} else {
69-
p.cancel(warningMessage);
70-
}
71-
process.exit(1);
72-
}
73-
7451
const packageJson = new PackageJson();
75-
// Project directory check
76-
await packageJson.load();
52+
packageJson.verifyPackageManager();
53+
await packageJson.load(); // Project directory check
54+
await packageJson.validateUserAgentConsistency();
7755

7856
// Git clean check
7957
if (options.force !== true && !isGitClean()) {
@@ -140,7 +118,7 @@ ${c.cyan("npx @solvro/config")}`;
140118

141119
if (projectType === "node") {
142120
p.cancel(
143-
`Nie znaleziono ani ${c.magenta("Adonis")}'a, ${c.cyan("React")}'a, ani ${c.white("NestJS")}'a. Musisz ręcznie konfigurować projekt.`,
121+
`Nie znaleziono ani ${c.magenta("Adonis")}-a, ${c.cyan("React")}-a, ani ${c.white("NestJS")}-a. Musisz ręcznie konfigurować projekt.`,
144122
);
145123
process.exit(1);
146124
}
@@ -151,7 +129,7 @@ ${c.cyan("npx @solvro/config")}`;
151129
} else {
152130
if (!(await packageJson.isESM())) {
153131
const isConfirmed = await polishConfirm({
154-
message: `Twój projekt nie używa ESM (brak type: "module" w package.json). Czy chcesz to dodać? (Wymagane by kontynuować)`,
132+
message: `Twój projekt nie używa ESM (brak "type": "module" w package.json). Czy chcesz to dodać? (Wymagane by kontynuować)`,
155133
});
156134

157135
if (p.isCancel(isConfirmed) || !isConfirmed) {
@@ -209,7 +187,7 @@ ${c.cyan("npx @solvro/config")}`;
209187
{
210188
value: "gh-action",
211189
label: c.bold("GitHub Actions"),
212-
hint: "automatyczne testy na Githubie",
190+
hint: "automatyczne testy na GitHubie",
213191
},
214192
{
215193
value: "commitlint",
@@ -253,6 +231,9 @@ ${c.cyan("npx @solvro/config")}`;
253231
}
254232

255233
await packageJson.clearInstall();
234+
if (toolsToInstall.includes("prettier")) {
235+
await packageJson.localExecute("prettier", "--write", "package.json");
236+
}
256237

257238
const printSuccess = isNonInteractive ? console.info : p.outro;
258239
printSuccess("✅ Konfiguracja zakończona pomyślnie!");

src/cli/install-commitlint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const installCommitLint = async () => {
1717

1818
await writeFile(
1919
path.join(root, ".husky/commit-msg"),
20-
'npx commitlint --edit "$1"\n',
20+
`${packageJson.manager.localExecute} commitlint --edit "$1"\n`,
2121
);
2222

2323
await writeFile(path.join(root, ".commitlintrc.js"), commitlint());

src/cli/install-ga.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export const installGithubActions = async () => {
2222
await fs.mkdir(ghWorkflowsDirectory, { recursive: true });
2323

2424
const type = await packageJson.getProjectType();
25+
const manager = packageJson.manager;
26+
27+
// Get pnpm version dynamically when using pnpm
28+
const pnpmVersion =
29+
manager.name === "pnpm" ? await packageJson.getPnpmVersion() : undefined;
2530

2631
const withCommitlint = await packageJson.hasPackage("@commitlint/cli");
2732

@@ -38,12 +43,14 @@ export const installGithubActions = async () => {
3843
adonisCi({
3944
nodeVersion: "22",
4045
withCommitlint,
46+
manager,
47+
pnpmVersion,
4148
}),
4249
);
4350

4451
await fs.writeFile(
4552
path.join(ghWorkflowsDirectory, "db.yml"),
46-
adonisMigrationsCi(),
53+
adonisMigrationsCi({ nodeVersion: "22", manager, pnpmVersion }),
4754
);
4855
}
4956

@@ -56,6 +63,8 @@ export const installGithubActions = async () => {
5663
nodeVersion: "22",
5764
withCommitlint,
5865
usingNextJs,
66+
manager,
67+
pnpmVersion,
5968
}),
6069
);
6170

@@ -70,6 +79,8 @@ export const installGithubActions = async () => {
7079
nestjsCi({
7180
nodeVersion: "22",
7281
withCommitlint,
82+
manager,
83+
pnpmVersion,
7384
}),
7485
);
7586
}

src/cli/install-husky.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import assert from "node:assert";
22

3-
import { $$ } from "../utils/$$";
43
import { PackageJson } from "../utils/package-json";
54

65
const packageJson = new PackageJson();
76

87
export const installHusky = async () => {
98
if (!(await packageJson.hasPackage("husky"))) {
109
await packageJson.install("husky", { dev: true });
11-
await $$`npx husky init`;
10+
await packageJson.localExecute("husky", "init");
1211
}
1312

1413
await packageJson.load();

src/cli/install-lint-staged.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import assert from "node:assert";
22
import { writeFile } from "node:fs/promises";
3+
import path from "node:path";
34

5+
import { projectRoot } from "../utils/git-root";
46
import { PackageJson } from "../utils/package-json";
57
import { installHusky } from "./install-husky";
68

@@ -15,7 +17,10 @@ export const installLintStaged = async () => {
1517

1618
await packageJson.install("lint-staged", { dev: true });
1719

18-
await writeFile(".husky/pre-commit", "npx lint-staged\n");
20+
await writeFile(
21+
path.join(projectRoot(), ".husky/pre-commit"),
22+
`${packageJson.manager.localExecute} lint-staged\n`,
23+
);
1924

2025
packageJson.json["lint-staged"] = {
2126
"*": "prettier -w --ignore-unknown",

0 commit comments

Comments
 (0)