Skip to content

Commit d8771dc

Browse files
committed
Simplify installation
1 parent 5bc1fef commit d8771dc

File tree

13 files changed

+180
-208
lines changed

13 files changed

+180
-208
lines changed

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,16 @@ run alternativeVersionPrettier vs originalVersionPrettier
2525

2626
Required.
2727

28-
There are 3 ways to specify.
28+
There are 2 ways to specify.
2929

30-
1. Versions (e.g. `2.0.0`, `1.7.1`)
31-
2. Repository name + ref (e.g. `sosukesuzuki/prettier#2f3fc241f8cb1867a0a3073ceac9d662e4b25fab`).
32-
3. Pull Request number on [prettier/prettier](https://github.com/prettier/prettier) repository (e.g. `#110168`).
30+
1. Versions or repository name + ref (e.g. `2.0.0`, `1.7.1`, or `sosukesuzuki/prettier#2f3fc241f8cb1867a0a3073ceac9d662e4b25fab`), it's installed directly with `yarn add`, so anything that [`yarn add`](https://yarnpkg.com/cli/add) allows
31+
2. Pull Request number on [prettier/prettier](https://github.com/prettier/prettier) repository (e.g. `#110168`).
3332

3433
### `originalVersionPrettier`
3534

3635
Optional.
3736

38-
In default, use `prettier/prettier#main`.
37+
In default, use `prettier/prettier`.
3938

4039
Also, you can specify with the logic same as `alternativeVersionPrettier`.
4140

@@ -46,11 +45,11 @@ run #110168
4645
```
4746

4847
```
49-
run #110168 vs sosukesuzuki/prettier#main
48+
run #110168 vs sosukesuzuki/prettier#fix-foo
5049
```
5150

5251
```
53-
run sosukesuzuki/prettier#main vs 1.8.1
52+
run sosukesuzuki/prettier#fix-foo vs 1.8.1
5453
```
5554

5655
## Add new project

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"npm-run-all": "^4.1.5",
4040
"outdent": "^0.8.0",
4141
"prettier": "3.6.2",
42+
"temp-dir": "^3.0.0",
4243
"typescript": "^5.9.3",
4344
"typescript-eslint": "^8.46.2",
4445
"vitest": "^4.0.6"

src/configuration.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import path from "path";
22
import ci from "ci-info";
33

44
export const cwd = process.cwd();
5-
export const prettierRepositoryPath = path.join(cwd, "./prettier");
65
export const targetRepositoriesPath = path.join(cwd, "./repos");
76
export const isCI = ci.isCI;
87
export const authToken = process.env.NODE_AUTH_TOKEN ?? "nothing";
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import fs from 'node:fs/promises'
2+
import os from 'node:os'
3+
import path from 'node:path';
4+
import crypto from "node:crypto";
5+
6+
export async function createTemporaryDirectory() {
7+
const directory = path.join(
8+
// The following quoted from https://github.com/es-tooling/module-replacements/blob/27d1acd38f19741e31d2eae561a5c8a914373fc5/docs/modules/tempy.md?plain=1#L20-L21, not sure if it's true
9+
// MacOS and possibly some other platforms return a symlink from `os.tmpdir`.
10+
// For some applications, this can cause problems; thus, we use `realpath`.
11+
await fs.realpath(os.tmpdir()),
12+
crypto.randomBytes(16).toString("hex"),
13+
);
14+
15+
fs.mkdir(directory);
16+
17+
return {
18+
path: directory,
19+
dispatch: () => destroyTemporaryDirectory(directory)
20+
};
21+
}
22+
23+
async function destroyTemporaryDirectory(directory: string) {
24+
await fs.rm(directory, {recursive: true, force: true})
25+
}
26+
27+
export type TemporaryDirectory = Awaited<ReturnType<typeof createTemporaryDirectory>>

src/execute/index.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,21 @@
1-
import { existsSync } from "fs";
21
import { Command } from "../parse.ts";
32
import { getPrettyHeadCommitHash } from "./get-pretty-head-commit-hash.ts";
43
import { preparePrettierIgnoreFile } from "./prepare-prettier-ignore-file.ts";
54
import { runPrettier } from "./run-prettier.ts";
6-
import { setupPrettierRepository } from "./setup-repository.ts";
75
import * as configuration from "../configuration.ts";
86
import * as git from "../tools/git.ts";
97
import * as logger from "../logger.ts";
108
import { getProjects, getTargetRepositoryPath } from "../projects.ts";
9+
import {installPrettier} from './install-prettier.ts'
1110

1211
export interface ExecuteResultEntry {
1312
commitHash: string;
1413
diff: string;
1514
}
1615

17-
async function clonePrettier() {
18-
if (!existsSync(configuration.prettierRepositoryPath)) {
19-
await logger.log("Cloning Prettier repository...");
20-
await git.clone(
21-
"https://github.com/prettier/prettier.git",
22-
"./prettier",
23-
configuration.cwd,
24-
);
25-
}
26-
}
27-
2816
export async function execute({
29-
alternativePrettier,
30-
originalPrettier,
17+
originalPrettier: originalPrettierVersion,
18+
alternativePrettier: alternativePrettierVersion,
3119
}: Command): Promise<ExecuteResultEntry[]> {
3220
const projects = await getProjects();
3321
const commitHashes = await Promise.all(
@@ -36,18 +24,16 @@ export async function execute({
3624
),
3725
);
3826

39-
await clonePrettier();
40-
4127
// Setup originalVersionPrettier
4228
await logger.log("Setting up originalVersionPrettier...");
43-
await setupPrettierRepository(originalPrettier);
29+
const originalPrettier = await installPrettier(originalPrettierVersion);
4430
// Run originalVersionPrettier
4531
await logger.log("Running originalVersionPrettier...");
4632
await Promise.all(
4733
projects.map(async (project) => {
4834
const targetRepositoryPath = getTargetRepositoryPath(project);
4935
await preparePrettierIgnoreFile(project);
50-
await runPrettier(configuration.prettierRepositoryPath, project);
36+
await runPrettier(originalPrettier, project);
5137
await git.add(".", targetRepositoryPath);
5238
await git.commitAllowEmptyNoVerify(
5339
"Fixed by originalVersionPrettier",
@@ -56,16 +42,19 @@ export async function execute({
5642
}),
5743
);
5844

45+
await originalPrettier.dispatch()
46+
5947
// Setup alternativeVersionPrettier
6048
await logger.log("Setting up alternativeVersionPrettier...");
61-
await setupPrettierRepository(alternativePrettier);
49+
const alternativePrettier = await installPrettier(alternativePrettierVersion);
6250
// Run alternativeVersionPrettier
6351
await logger.log("Running alternativeVersionPrettier...");
6452
await Promise.all(
6553
projects.map(async (project) => {
66-
await runPrettier(configuration.prettierRepositoryPath, project);
54+
await runPrettier(alternativePrettier, project);
6755
}),
6856
);
57+
await alternativePrettier.dispatch()
6958

7059
const diffs = await Promise.all(
7160
projects.map(getTargetRepositoryPath).map(git.diffRepository),

src/execute/install-prettier.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import path from "node:path";
2+
import {
3+
PrettierVersion,
4+
PrettierPullRequest,
5+
sourceTypes
6+
} from "../parse.ts";
7+
import * as configuration from "../configuration.ts";
8+
import * as brew from "../tools/brew.ts";
9+
import * as gh from "../tools/gh.ts";
10+
import * as yarn from "../tools/yarn.ts";
11+
import * as npm from "../tools/npm.ts";
12+
import * as unix from "../tools/unix.ts";
13+
import {createTemporaryDirectory, type TemporaryDirectory} from './create-temporary-directory.ts'
14+
15+
export type InstalledPrettier = Awaited<ReturnType<typeof installPrettier>>
16+
17+
export async function installPrettier(
18+
prettierVersion: PrettierVersion,
19+
) {
20+
let version: string
21+
let pullRequestDirectory: TemporaryDirectory | undefined
22+
if (prettierVersion.type === sourceTypes.pullRequest) {
23+
({version, directory: pullRequestDirectory} = await getPullRequest(prettierVersion.number) )
24+
} else {
25+
({version} = prettierVersion)
26+
}
27+
28+
29+
const directory = await createTemporaryDirectory()
30+
const {path: cwd} = directory
31+
await yarn.init(['-y'], {cwd})
32+
await yarn.add([`prettier@${version}`],{cwd})
33+
34+
await pullRequestDirectory?.dispatch()
35+
36+
return {
37+
dispatch: () => {directory.dispatch()},
38+
bin: path.join(cwd, 'node_modules/prettier/bin/prettier.cjs'),
39+
name: prettierVersion.raw
40+
}
41+
}
42+
43+
async function existsGh() {
44+
return !(await unix.which("gh")).includes("gh not found");
45+
}
46+
47+
async function getPullRequest(
48+
pullRequestNumber: PrettierPullRequest['number'],
49+
) {
50+
if (!(await existsGh())) {
51+
await brew.install("gh");
52+
}
53+
if (configuration.authToken !== "nothing") {
54+
// running locally, `gh` can be already authenticated
55+
await gh.authLoginWithToken(configuration.authToken);
56+
}
57+
58+
const directory = await createTemporaryDirectory()
59+
60+
await gh.prCheckout(pullRequestNumber, directory.path);
61+
const {stdout} = await npm.pack({cwd: directory.path});
62+
63+
return {
64+
directory,
65+
version: `file:${path.join(directory.path, stdout.trim())}`
66+
};
67+
}

src/execute/run-prettier.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,17 @@ import path from "path";
22
import spawn from "nano-spawn";
33
import { type Project, getTargetRepositoryPath } from "../projects.ts";
44
import * as yarn from "../tools/yarn.ts";
5+
import {type InstalledPrettier} from './install-prettier.ts'
56

67
export async function runPrettier(
7-
prettierRepositoryPath: string,
8+
prettier: InstalledPrettier,
89
project: Project,
910
): Promise<void> {
1011
const repositoryPath = getTargetRepositoryPath(project);
1112
const glob = project.glob ?? ["."];
1213

13-
const prettierRepositoryBinPath = path.join(
14-
prettierRepositoryPath,
15-
"./bin/prettier.js",
16-
);
17-
1814
const args = [
19-
prettierRepositoryBinPath,
15+
prettier.bin,
2016
"--write",
2117
"--no-color",
2218
...(Array.isArray(glob) ? glob : [glob]),

src/execute/setup-repository.ts

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

src/log-text.ts

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
11
import * as configuration from "./configuration.ts";
22
import { ExecuteResultEntry } from "./execute/index.ts";
3-
import { Command, PrettierRepositorySource } from "./parse.ts";
3+
import { Command } from "./parse.ts";
44

5-
function getPrettierRepositorySourceText(
6-
prettierRepositorySource: PrettierRepositorySource,
7-
) {
8-
switch (prettierRepositorySource.type) {
9-
case "prNumber": {
10-
return configuration.isCI
11-
? `prettier/prettier#${prettierRepositorySource.prNumber}`
12-
: `https://github.com/prettier/prettier/pull/${prettierRepositorySource.prNumber}`;
13-
}
14-
case "repositoryAndRef": {
15-
return configuration.isCI
16-
? `${prettierRepositorySource.repositoryName}@${prettierRepositorySource.ref}`
17-
: `https://github.com/${prettierRepositorySource.repositoryName}/blob/${prettierRepositorySource.ref}/README.md`;
18-
}
19-
case "version": {
20-
const versionUrl = `https://github.com/prettier/prettier/tree/${prettierRepositorySource.version}`;
21-
return configuration.isCI
22-
? `[prettier/prettier@${prettierRepositorySource.version}](${versionUrl})`
23-
: versionUrl;
24-
}
25-
}
26-
}
275
function getLogTitle(command: Command): string {
28-
const alternativePrettierRepositoryText = getPrettierRepositorySourceText(
29-
command.alternativePrettier,
30-
);
31-
const originalPrettierRepositoryText = getPrettierRepositorySourceText(
32-
command.originalPrettier,
33-
);
6+
const alternativePrettierRepositoryText = command.alternativePrettier.raw;
7+
const originalPrettierRepositoryText = command.originalPrettier.raw;
348
if (configuration.isCI) {
359
return `**${alternativePrettierRepositoryText} VS ${originalPrettierRepositoryText}**`;
3610
} else {

0 commit comments

Comments
 (0)