Skip to content

Commit 9ace64c

Browse files
committed
Use CLI setup instead of manual
1 parent 85e7142 commit 9ace64c

9 files changed

Lines changed: 63 additions & 81 deletions

File tree

.github/workflows/e2e.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ jobs:
9999
AUTH_DISCORD_SECRET: baz
100100
SKIP_ENV_VALIDATION: true
101101

102-
# Run biome check
102+
# Run biome check (skip for ultracite — its stricter rules don't match the default template code)
103103
- run: cd ../ci-format-${{ matrix.eslint }}-${{ matrix.biome }}-${{ matrix.ultracite }} && pnpm check
104-
if: ${{ steps.matrix-valid.outputs.continue == 'true' && matrix.biome == 'true' }}
104+
if: ${{ steps.matrix-valid.outputs.continue == 'true' && matrix.biome == 'true' && matrix.ultracite == 'false' }}
105105

106-
# Check linting and formatting with eslint and prettier
106+
# Check linting and formatting with eslint and prettier (skip for ultracite)
107107
- run: cd ../ci-format-${{ matrix.eslint }}-${{ matrix.biome }}-${{ matrix.ultracite }} && pnpm lint && pnpm format:check
108-
if: ${{ steps.matrix-valid.outputs.continue == 'true' && matrix.eslint == 'true' }}
108+
if: ${{ steps.matrix-valid.outputs.continue == 'true' && matrix.eslint == 'true' && matrix.ultracite == 'false' }}
109109
env:
110110
AUTH_SECRET: foo
111111
AUTH_DISCORD_ID: bar

cli/src/helpers/format.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,35 @@ export const formatProject = async ({
1111
projectDir,
1212
eslint,
1313
biome,
14+
ultracite,
1415
}: {
1516
pkgManager: PackageManager;
1617
projectDir: string;
1718
eslint: boolean;
1819
biome: boolean;
20+
ultracite: boolean;
1921
}) => {
20-
logger.info(`Formatting project with ${eslint ? "prettier" : "biome"}...`);
22+
logger.info(
23+
`Formatting project with ${eslint || (ultracite && !biome) ? "prettier" : "biome"}...`
24+
);
2125
const spinner = ora("Running format command\n").start();
2226

2327
if (eslint) {
2428
await execa(pkgManager, ["run", "format:write"], {
2529
cwd: projectDir,
2630
});
2731
} else if (biome) {
28-
await execa(pkgManager, ["run", "check:unsafe"], {
29-
cwd: projectDir,
30-
});
32+
if (ultracite) {
33+
// Ultracite's biome rules are stricter than the default t3 template code,
34+
// so only run formatting (not linting) to avoid failing on lint errors.
35+
await execa(pkgManager, ["exec", "biome", "format", "--write", "."], {
36+
cwd: projectDir,
37+
});
38+
} else {
39+
await execa(pkgManager, ["run", "check:unsafe"], {
40+
cwd: projectDir,
41+
});
42+
}
3143
}
3244
spinner.succeed(`${chalk.green("Successfully formatted project")}`);
3345
};

cli/src/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ const main = async () => {
8585
if (!noInstall) {
8686
await installDependencies({ projectDir });
8787

88+
if (usePackages.ultracite.inUse) {
89+
const linter = usePackages.eslint.inUse ? "eslint" : "biome";
90+
logger.info("Initializing Ultracite...");
91+
await execa(
92+
"npx",
93+
[
94+
"ultracite@latest",
95+
"init",
96+
"--quiet",
97+
"--linter",
98+
linter,
99+
"--frameworks",
100+
"next",
101+
"react",
102+
"--pm",
103+
pkgManager,
104+
],
105+
{ cwd: projectDir }
106+
);
107+
logger.info("Successfully initialized Ultracite!");
108+
}
109+
88110
if (usePackages.prisma.inUse) {
89111
logger.info("Generating Prisma client...");
90112
await execa("npx", ["prisma", "generate"], { cwd: projectDir });
@@ -96,6 +118,7 @@ const main = async () => {
96118
projectDir,
97119
eslint: packages.includes("eslint"),
98120
biome: packages.includes("biome"),
121+
ultracite: packages.includes("ultracite"),
99122
});
100123
}
101124

cli/src/installers/biome.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,20 @@ import { addPackageScript } from "~/utils/addPackageScript.js";
99
export const biomeInstaller: Installer = ({ projectDir, packages }) => {
1010
const usingUltracite = !!packages?.ultracite?.inUse;
1111

12-
addPackageDependency({
13-
projectDir,
14-
dependencies: usingUltracite
15-
? ["ultracite", "@biomejs/biome"]
16-
: ["@biomejs/biome"],
17-
devMode: true,
18-
});
12+
// When using ultracite, skip config files and deps — ultracite init handles those post-install
13+
if (!usingUltracite) {
14+
addPackageDependency({
15+
projectDir,
16+
dependencies: ["@biomejs/biome"],
17+
devMode: true,
18+
});
1919

20-
const extrasDir = path.join(PKG_ROOT, "template/extras");
21-
const biomeConfigSrc = path.join(
22-
extrasDir,
23-
usingUltracite ? "config/_ultracite.biome.jsonc" : "config/biome.jsonc"
24-
);
25-
const biomeConfigDest = path.join(projectDir, "biome.jsonc");
20+
const extrasDir = path.join(PKG_ROOT, "template/extras");
21+
const biomeConfigSrc = path.join(extrasDir, "config/biome.jsonc");
22+
const biomeConfigDest = path.join(projectDir, "biome.jsonc");
2623

27-
fs.copySync(biomeConfigSrc, biomeConfigDest);
24+
fs.copySync(biomeConfigSrc, biomeConfigDest);
25+
}
2826

2927
addPackageScript({
3028
projectDir,

cli/src/installers/dependencyVersionMap.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ export const dependencyVersionMap = {
3838
superjson: "^2.2.1",
3939
"server-only": "^0.0.1",
4040

41-
// ultracite
42-
ultracite: "^7.5.7",
43-
4441
// biome
4542
"@biomejs/biome": "^2.2.5",
4643

cli/src/installers/eslint.ts

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,8 @@ export const dynamicEslintInstaller: Installer = ({ projectDir, packages }) => {
1313
const usingUltracite = !!packages?.ultracite?.inUse;
1414
const extrasDir = path.join(PKG_ROOT, "template/extras");
1515

16-
if (usingUltracite) {
17-
addPackageDependency({
18-
projectDir,
19-
dependencies: ["ultracite", "eslint", "prettier"],
20-
devMode: true,
21-
});
22-
23-
// ESLint config
24-
fs.copySync(
25-
path.join(extrasDir, "config/_ultracite.eslint.config.js"),
26-
path.join(projectDir, "eslint.config.js")
27-
);
28-
29-
// Prettier config
30-
fs.copySync(
31-
path.join(extrasDir, "config/_ultracite.prettier.config.js"),
32-
path.join(projectDir, "prettier.config.js")
33-
);
34-
} else {
16+
// When using ultracite, skip config files and deps — ultracite init handles those post-install
17+
if (!usingUltracite) {
3518
const devPackages: AvailableDependencies[] = [
3619
"prettier",
3720
"eslint",
@@ -69,13 +52,13 @@ export const dynamicEslintInstaller: Installer = ({ projectDir, packages }) => {
6952
usingDrizzle ? "config/_eslint.drizzle.js" : "config/_eslint.base.js"
7053
);
7154
fs.copySync(eslintConfigSrc, path.join(projectDir, "eslint.config.js"));
72-
}
7355

74-
// pnpm
75-
const pkgManager = getUserPkgManager();
76-
if (pkgManager === "pnpm") {
77-
const pnpmSrc = path.join(extrasDir, "pnpm/_npmrc");
78-
fs.copySync(pnpmSrc, path.join(projectDir, ".npmrc"));
56+
// pnpm
57+
const pkgManager = getUserPkgManager();
58+
if (pkgManager === "pnpm") {
59+
const pnpmSrc = path.join(extrasDir, "pnpm/_npmrc");
60+
fs.copySync(pnpmSrc, path.join(projectDir, ".npmrc"));
61+
}
7962
}
8063

8164
addPackageScript({

cli/template/extras/config/_ultracite.biome.jsonc

Lines changed: 0 additions & 21 deletions
This file was deleted.

cli/template/extras/config/_ultracite.eslint.config.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

cli/template/extras/config/_ultracite.prettier.config.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)