sweepi 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/{chunk-GTTA7GGB.js → chunk-BWQN4NL3.js} +70 -1
- package/dist/cli.js +34 -13
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,11 +5,19 @@ Run Sweepit lint rules against a project without changing that project's depende
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx sweepi
|
|
8
|
+
npx sweepi [project-dir]
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
If `~/.sweepi` has not been initialized yet, Sweepi will initialize it first.
|
|
12
12
|
|
|
13
|
+
By default, Sweepi lints changed files only (staged, unstaged, and untracked), limited to `.ts` and `.tsx`.
|
|
14
|
+
|
|
15
|
+
Use `--all` to lint all TypeScript files in the project:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx sweepi [project-dir] --all
|
|
19
|
+
```
|
|
20
|
+
|
|
13
21
|
## Explicit initialization
|
|
14
22
|
|
|
15
23
|
```bash
|
|
@@ -26,7 +34,7 @@ This creates `~/.sweepi`, writes `~/.sweepi/eslint.config.mjs`, and installs:
|
|
|
26
34
|
Sweepi executes ESLint from the private toolchain directory:
|
|
27
35
|
|
|
28
36
|
```bash
|
|
29
|
-
~/.sweepi/node_modules/.bin/eslint --config ~/.sweepi/eslint.config.mjs <
|
|
37
|
+
~/.sweepi/node_modules/.bin/eslint --config ~/.sweepi/eslint.config.mjs <changed-files>
|
|
30
38
|
```
|
|
31
39
|
|
|
32
40
|
This keeps project dependencies and lockfiles untouched.
|
|
@@ -22,7 +22,10 @@ var TOOLCHAIN_PACKAGE_JSON_CONTENT = JSON.stringify(
|
|
|
22
22
|
);
|
|
23
23
|
var TOOLCHAIN_CONFIG_CONTENT = `import sweepitPlugin from 'eslint-plugin-sweepit';
|
|
24
24
|
|
|
25
|
+
const files = ['**/*.ts', '**/*.tsx'];
|
|
25
26
|
const ignores = [
|
|
27
|
+
'**/*.test.*',
|
|
28
|
+
'**/*.spec.*',
|
|
26
29
|
'**/node_modules/**',
|
|
27
30
|
'**/.next/**',
|
|
28
31
|
'**/dist/**',
|
|
@@ -32,7 +35,13 @@ const ignores = [
|
|
|
32
35
|
'**/out/**',
|
|
33
36
|
];
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
const withFiles = (config) => ({ ...config, files });
|
|
39
|
+
|
|
40
|
+
export default [
|
|
41
|
+
{ ignores },
|
|
42
|
+
...sweepitPlugin.configs.core.map(withFiles),
|
|
43
|
+
...sweepitPlugin.configs.react.map(withFiles),
|
|
44
|
+
];
|
|
36
45
|
`;
|
|
37
46
|
async function initializeToolchain(options = {}) {
|
|
38
47
|
assertSupportedNodeVersion();
|
|
@@ -101,7 +110,9 @@ async function runSweepi(projectDirectory, options = {}) {
|
|
|
101
110
|
);
|
|
102
111
|
const configPath = path.join(toolchainDirectory, TOOLCHAIN_CONFIG_NAME);
|
|
103
112
|
const runLintCommand = options.runLintCommand ?? runLintCommandWithExecutable;
|
|
113
|
+
const listChangedFiles = options.listChangedFiles ?? listChangedFilesFromGit;
|
|
104
114
|
const onStatus = options.onStatus;
|
|
115
|
+
const lintAllFiles = options.all === true;
|
|
105
116
|
const eslintInstalled = await pathExists(eslintBinaryPath);
|
|
106
117
|
const pluginInstalled = await pathExists(pluginPackagePath);
|
|
107
118
|
const configInstalled = await pathExists(configPath);
|
|
@@ -111,12 +122,70 @@ async function runSweepi(projectDirectory, options = {}) {
|
|
|
111
122
|
);
|
|
112
123
|
}
|
|
113
124
|
onStatus?.(`Using Sweepi toolchain in ${toolchainDirectory}`);
|
|
125
|
+
if (!lintAllFiles) {
|
|
126
|
+
const changedFiles = await listChangedFiles(resolvedProjectDirectory);
|
|
127
|
+
if (changedFiles.length === 0) {
|
|
128
|
+
onStatus?.("No changed files to lint.");
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
return runLintCommand(
|
|
132
|
+
eslintBinaryPath,
|
|
133
|
+
[
|
|
134
|
+
"--config",
|
|
135
|
+
configPath,
|
|
136
|
+
"--no-error-on-unmatched-pattern",
|
|
137
|
+
...changedFiles.map((filePath) => path.resolve(resolvedProjectDirectory, filePath))
|
|
138
|
+
],
|
|
139
|
+
resolvedProjectDirectory
|
|
140
|
+
);
|
|
141
|
+
}
|
|
114
142
|
return runLintCommand(
|
|
115
143
|
eslintBinaryPath,
|
|
116
144
|
["--config", configPath, resolvedProjectDirectory],
|
|
117
145
|
resolvedProjectDirectory
|
|
118
146
|
);
|
|
119
147
|
}
|
|
148
|
+
async function listChangedFilesFromGit(projectDirectory) {
|
|
149
|
+
const [unstagedFiles, stagedFiles, untrackedFiles] = await Promise.all([
|
|
150
|
+
runGitListCommand(projectDirectory, ["diff", "--name-only", "--diff-filter=ACMR"]),
|
|
151
|
+
runGitListCommand(projectDirectory, ["diff", "--cached", "--name-only", "--diff-filter=ACMR"]),
|
|
152
|
+
runGitListCommand(projectDirectory, ["ls-files", "--others", "--exclude-standard"])
|
|
153
|
+
]);
|
|
154
|
+
return Array.from(/* @__PURE__ */ new Set([...unstagedFiles, ...stagedFiles, ...untrackedFiles]));
|
|
155
|
+
}
|
|
156
|
+
function runGitListCommand(projectDirectory, args) {
|
|
157
|
+
return new Promise((resolve2, reject) => {
|
|
158
|
+
const child = childProcess.spawn("git", args, {
|
|
159
|
+
cwd: projectDirectory,
|
|
160
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
161
|
+
env: process.env
|
|
162
|
+
});
|
|
163
|
+
let output = "";
|
|
164
|
+
let errorOutput = "";
|
|
165
|
+
child.stdout.on("data", (chunk) => {
|
|
166
|
+
output += chunk.toString();
|
|
167
|
+
});
|
|
168
|
+
child.stderr.on("data", (chunk) => {
|
|
169
|
+
errorOutput += chunk.toString();
|
|
170
|
+
});
|
|
171
|
+
child.on("error", (error) => {
|
|
172
|
+
reject(error);
|
|
173
|
+
});
|
|
174
|
+
child.on("exit", (code) => {
|
|
175
|
+
if (code !== 0) {
|
|
176
|
+
reject(
|
|
177
|
+
new Error(
|
|
178
|
+
`Failed to list changed files with "git ${args.join(" ")}" in ${projectDirectory}.
|
|
179
|
+
${errorOutput.trim()}`
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const files = output.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
185
|
+
resolve2(files);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
120
189
|
async function ensureFile(filePath, content) {
|
|
121
190
|
const exists = await pathExists(filePath);
|
|
122
191
|
if (!exists) {
|
package/dist/cli.js
CHANGED
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
initializeToolchain,
|
|
4
4
|
runSweepi
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BWQN4NL3.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
8
8
|
async function run() {
|
|
9
|
-
const
|
|
10
|
-
if (
|
|
9
|
+
const [firstArgument, ...restArguments] = process.argv.slice(2);
|
|
10
|
+
if (firstArgument === void 0 || firstArgument === "--help" || firstArgument === "-h") {
|
|
11
11
|
printHelp();
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
if (
|
|
15
|
-
const
|
|
16
|
-
const forceReset = parseForceResetOption(initArguments);
|
|
14
|
+
if (firstArgument === "init") {
|
|
15
|
+
const forceReset = parseForceResetOption(restArguments);
|
|
17
16
|
const initialization = await initializeToolchain({
|
|
18
17
|
onStatus: logStatus,
|
|
19
18
|
forceReset
|
|
@@ -31,21 +30,22 @@ async function run() {
|
|
|
31
30
|
);
|
|
32
31
|
return;
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
const runArguments = [firstArgument, ...restArguments];
|
|
34
|
+
const parsedRunOptions = parseRunOptions(runArguments);
|
|
35
|
+
const lintExitCode = await runSweepi(parsedRunOptions.projectDirectory, {
|
|
36
|
+
onStatus: logStatus,
|
|
37
|
+
all: parsedRunOptions.all
|
|
39
38
|
});
|
|
40
39
|
process.exitCode = lintExitCode;
|
|
41
40
|
}
|
|
42
41
|
function printHelp() {
|
|
43
42
|
process.stdout.write(`Usage:
|
|
44
|
-
sweepi
|
|
43
|
+
sweepi [project-dir] [--all]
|
|
45
44
|
sweepi init
|
|
46
45
|
|
|
47
46
|
Commands:
|
|
48
|
-
|
|
47
|
+
[project-dir] Run eslint on changed ts/tsx files (default: current directory)
|
|
48
|
+
--all Run eslint on all ts/tsx files
|
|
49
49
|
init [--force, -f] Create ~/.sweepi and install rules
|
|
50
50
|
|
|
51
51
|
Tip:
|
|
@@ -67,6 +67,27 @@ function parseForceResetOption(argumentsList) {
|
|
|
67
67
|
}
|
|
68
68
|
return forceReset;
|
|
69
69
|
}
|
|
70
|
+
function parseRunOptions(argumentsList) {
|
|
71
|
+
let projectDirectory = ".";
|
|
72
|
+
let all = false;
|
|
73
|
+
for (const argument of argumentsList) {
|
|
74
|
+
if (argument === "--all") {
|
|
75
|
+
all = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (argument.startsWith("-")) {
|
|
79
|
+
throw new Error(`Unknown flag "${argument}". Try "sweepi --help".`);
|
|
80
|
+
}
|
|
81
|
+
if (projectDirectory !== ".") {
|
|
82
|
+
throw new Error(`Unexpected argument "${argument}". Try "sweepi --help".`);
|
|
83
|
+
}
|
|
84
|
+
projectDirectory = argument;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
projectDirectory,
|
|
88
|
+
all
|
|
89
|
+
};
|
|
90
|
+
}
|
|
70
91
|
try {
|
|
71
92
|
await run();
|
|
72
93
|
} catch (error) {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,9 @@ interface InitializeToolchainResult {
|
|
|
11
11
|
interface RunSweepiOptions {
|
|
12
12
|
homeDirectory?: string;
|
|
13
13
|
runLintCommand?: (command: string, args: string[], cwd: string) => Promise<number>;
|
|
14
|
+
listChangedFiles?: (projectDirectory: string) => Promise<string[]>;
|
|
14
15
|
onStatus?: (message: string) => void;
|
|
16
|
+
all?: boolean;
|
|
15
17
|
}
|
|
16
18
|
declare function initializeToolchain(options?: InitializeToolchainOptions): Promise<InitializeToolchainResult>;
|
|
17
19
|
declare function runSweepi(projectDirectory: string, options?: RunSweepiOptions): Promise<number>;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sweepi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Run Sweepit lint rules without modifying project dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"typescript": "^5.9.2",
|
|
34
34
|
"vitest": "^2.1.3"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "1d3f7a500a44c4caff15c44b5b0cd63df3e2f87a"
|
|
37
37
|
}
|