meocli 0.0.2 → 0.0.5
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 +24 -11
- package/dist/commands/{prettier → pr}/index.d.ts +4 -2
- package/dist/commands/pr/index.js +173 -0
- package/dist/consts/prettierrc.d.ts +4 -1
- package/dist/consts/prettierrc.js +64 -34
- package/oclif.manifest.json +8 -7
- package/package.json +4 -1
- package/dist/commands/prettier/index.js +0 -136
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A new CLI generated with oclif
|
|
|
9
9
|
<!-- toc -->
|
|
10
10
|
* [meocli](#meocli)
|
|
11
11
|
* [Dev](#dev)
|
|
12
|
+
* [Publish](#publish)
|
|
12
13
|
* [Usage](#usage)
|
|
13
14
|
* [Commands](#commands)
|
|
14
15
|
<!-- tocstop -->
|
|
@@ -16,9 +17,19 @@ A new CLI generated with oclif
|
|
|
16
17
|
# Dev
|
|
17
18
|
|
|
18
19
|
```sh-session
|
|
20
|
+
<!-- demo -->
|
|
19
21
|
$ pnpm run dev hello world
|
|
20
22
|
$ pnpm run prod hello world
|
|
21
23
|
$ pnpm run dev hello foo -f bar
|
|
24
|
+
<!-- prettier -->
|
|
25
|
+
$ pnpm run dev pr ./tmp/test.svg
|
|
26
|
+
$ pnpm run dev pr ./tmp/test.json --config=auto --ignore=auto
|
|
27
|
+
$ pnpm run dev pr ./tmp/test.svg --config=built_in --ignore=auto
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
# Publish
|
|
31
|
+
|
|
32
|
+
```sh-session
|
|
22
33
|
$ pnpm login
|
|
23
34
|
$ pnpm build
|
|
24
35
|
$ pnpm publish
|
|
@@ -32,7 +43,7 @@ $ npm install -g meocli
|
|
|
32
43
|
$ me COMMAND
|
|
33
44
|
running command...
|
|
34
45
|
$ me (--version)
|
|
35
|
-
meocli/0.0.
|
|
46
|
+
meocli/0.0.5 win32-x64 node-v24.12.0
|
|
36
47
|
$ me --help [COMMAND]
|
|
37
48
|
USAGE
|
|
38
49
|
$ me COMMAND
|
|
@@ -56,7 +67,7 @@ USAGE
|
|
|
56
67
|
* [`me plugins uninstall [PLUGIN]`](#me-plugins-uninstall-plugin)
|
|
57
68
|
* [`me plugins unlink [PLUGIN]`](#me-plugins-unlink-plugin)
|
|
58
69
|
* [`me plugins update`](#me-plugins-update)
|
|
59
|
-
* [`me
|
|
70
|
+
* [`me pr FILEPATH`](#me-pr-filepath)
|
|
60
71
|
|
|
61
72
|
## `me hello PERSON`
|
|
62
73
|
|
|
@@ -80,7 +91,7 @@ EXAMPLES
|
|
|
80
91
|
hello friend from oclif! (./src/commands/hello/index.ts)
|
|
81
92
|
```
|
|
82
93
|
|
|
83
|
-
_See code: [src/commands/hello/index.ts](https://github.com/meme2046/meocli/blob/v0.0.
|
|
94
|
+
_See code: [src/commands/hello/index.ts](https://github.com/meme2046/meocli/blob/v0.0.5/src/commands/hello/index.ts)_
|
|
84
95
|
|
|
85
96
|
## `me hello world`
|
|
86
97
|
|
|
@@ -98,7 +109,7 @@ EXAMPLES
|
|
|
98
109
|
hello world! (./src/commands/hello/world.ts)
|
|
99
110
|
```
|
|
100
111
|
|
|
101
|
-
_See code: [src/commands/hello/world.ts](https://github.com/meme2046/meocli/blob/v0.0.
|
|
112
|
+
_See code: [src/commands/hello/world.ts](https://github.com/meme2046/meocli/blob/v0.0.5/src/commands/hello/world.ts)_
|
|
102
113
|
|
|
103
114
|
## `me help [COMMAND]`
|
|
104
115
|
|
|
@@ -410,29 +421,31 @@ DESCRIPTION
|
|
|
410
421
|
|
|
411
422
|
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.4.54/src/commands/plugins/update.ts)_
|
|
412
423
|
|
|
413
|
-
## `me
|
|
424
|
+
## `me pr FILEPATH`
|
|
414
425
|
|
|
415
426
|
Use Prettier to format file
|
|
416
427
|
|
|
417
428
|
```
|
|
418
429
|
USAGE
|
|
419
|
-
$ me
|
|
430
|
+
$ me pr FILEPATH [-c <value>] [--ignore <value>]
|
|
420
431
|
|
|
421
432
|
ARGUMENTS
|
|
422
433
|
FILEPATH file path that need to be formatted by Prettier
|
|
423
434
|
|
|
424
435
|
FLAGS
|
|
425
|
-
-c, --config=<value>
|
|
426
|
-
|
|
436
|
+
-c, --config=<value> [default: built_in] built_in:使用内置规则(默认值), 传入路径则是使用自定义配置,
|
|
437
|
+
auto:自动检测config file
|
|
438
|
+
--ignore=<value> [default: built_in] built_in:使用内置规则(默认值), 传入路径则是使用自定义规则,
|
|
439
|
+
auto:自动检测ignore file
|
|
427
440
|
|
|
428
441
|
DESCRIPTION
|
|
429
442
|
Use Prettier to format file
|
|
430
443
|
|
|
431
444
|
EXAMPLES
|
|
432
|
-
$ me
|
|
445
|
+
$ me pr ./tests/test.json
|
|
433
446
|
|
|
434
|
-
$ me
|
|
447
|
+
$ me pr ./src/file.ts --config ./.prettierrc.yaml
|
|
435
448
|
```
|
|
436
449
|
|
|
437
|
-
_See code: [src/commands/
|
|
450
|
+
_See code: [src/commands/pr/index.ts](https://github.com/meme2046/meocli/blob/v0.0.5/src/commands/pr/index.ts)_
|
|
438
451
|
<!-- commandsstop -->
|
|
@@ -6,11 +6,13 @@ export default class Prettier extends Command {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
|
-
config: import("@oclif/core/interfaces").OptionFlag<string
|
|
10
|
-
ignore: import("@oclif/core/interfaces").OptionFlag<string
|
|
9
|
+
config: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
ignore: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
};
|
|
12
12
|
run(): Promise<void>;
|
|
13
13
|
private detectPackageManager;
|
|
14
14
|
private findProjectPrettierConfig;
|
|
15
15
|
private findProjectPrettierIgnore;
|
|
16
|
+
private replacePluginArgs;
|
|
17
|
+
private resolvePluginPaths;
|
|
16
18
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
// import {spawn} from 'node:child_process'
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { platform } from 'node:os';
|
|
6
|
+
import { dirname, join } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { DEFAULT_ARGS, DEFAULT_PLUGINS } from '../../consts/prettierrc.js';
|
|
9
|
+
export default class Prettier extends Command {
|
|
10
|
+
static args = {
|
|
11
|
+
filePath: Args.string({
|
|
12
|
+
description: 'file path that need to be formatted by Prettier',
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static description = 'Use Prettier to format file';
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> <%= command.id %> ./tests/test.json',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> ./src/file.ts --config ./.prettierrc.yaml',
|
|
20
|
+
];
|
|
21
|
+
static flags = {
|
|
22
|
+
config: Flags.string({
|
|
23
|
+
char: 'c',
|
|
24
|
+
default: 'built_in',
|
|
25
|
+
description: 'built_in:使用内置规则(默认值), 传入路径则是使用自定义配置, auto:自动检测config file',
|
|
26
|
+
required: false,
|
|
27
|
+
}),
|
|
28
|
+
ignore: Flags.string({
|
|
29
|
+
default: 'built_in',
|
|
30
|
+
description: 'built_in:使用内置规则(默认值), 传入路径则是使用自定义规则, auto:自动检测ignore file',
|
|
31
|
+
required: false,
|
|
32
|
+
}),
|
|
33
|
+
// 'no-config': Flags.boolean({
|
|
34
|
+
// default: false,
|
|
35
|
+
// description: 'Disable config file detection',
|
|
36
|
+
// }),
|
|
37
|
+
// 'no-ignore': Flags.boolean({
|
|
38
|
+
// default: false,
|
|
39
|
+
// description: 'Disable ignore file detection',
|
|
40
|
+
// }),
|
|
41
|
+
};
|
|
42
|
+
async run() {
|
|
43
|
+
const { args, flags } = await this.parse(Prettier);
|
|
44
|
+
const { filePath } = args;
|
|
45
|
+
const { config, ignore } = flags;
|
|
46
|
+
// 检查文件是否存在
|
|
47
|
+
if (!existsSync(filePath)) {
|
|
48
|
+
this.error(`file『${filePath}』not found`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// 检测当前使用的包管理器
|
|
52
|
+
// const packageManager = this.detectPackageManager()
|
|
53
|
+
// 获取 prettier 可执行文件的路径
|
|
54
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
55
|
+
const __dirname = dirname(__filename);
|
|
56
|
+
const projectRoot = join(__dirname, '../../../'); // 回到项目根目录
|
|
57
|
+
let prettierBin = join(projectRoot, 'node_modules', '.bin', 'prettier');
|
|
58
|
+
if (platform() === 'win32') {
|
|
59
|
+
prettierBin += '.cmd';
|
|
60
|
+
}
|
|
61
|
+
if (!existsSync(prettierBin)) {
|
|
62
|
+
this.error(`prettier not found`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// 根据包管理器类型构建参数
|
|
66
|
+
let prettierArgs = ['--write', filePath];
|
|
67
|
+
if (ignore === 'built_in') {
|
|
68
|
+
prettierArgs.unshift('--ignore-path', join(projectRoot, '.prettierignore'));
|
|
69
|
+
}
|
|
70
|
+
else if (existsSync(ignore)) {
|
|
71
|
+
prettierArgs.unshift('--ignore-path', ignore);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const projectIgnore = this.findProjectPrettierIgnore();
|
|
75
|
+
if (projectIgnore) {
|
|
76
|
+
prettierArgs.unshift('--ignore-path', projectIgnore);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const resolvedPluginArgs = this.resolvePluginPaths(DEFAULT_PLUGINS, projectRoot);
|
|
80
|
+
const argsWithResolvedPlugins = this.replacePluginArgs(DEFAULT_ARGS, resolvedPluginArgs);
|
|
81
|
+
const completeArgs = [...argsWithResolvedPlugins, ...prettierArgs];
|
|
82
|
+
if (config === 'built_in') {
|
|
83
|
+
// 为插件参数使用绝对路径,避免全局安装时找不到插件
|
|
84
|
+
prettierArgs = completeArgs;
|
|
85
|
+
}
|
|
86
|
+
else if (existsSync(config)) {
|
|
87
|
+
prettierArgs.unshift('--config', config);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// 否则尝试查找项目中的配置文件
|
|
91
|
+
const projectConfig = this.findProjectPrettierConfig();
|
|
92
|
+
if (projectConfig) {
|
|
93
|
+
prettierArgs.unshift('--config', projectConfig);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// 为插件参数使用绝对路径,避免全局安装时找不到插件
|
|
97
|
+
prettierArgs = completeArgs;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
this.log(prettierBin);
|
|
101
|
+
this.log(JSON.stringify(prettierArgs));
|
|
102
|
+
// this.log(`Formatting file: ${filePath}`)
|
|
103
|
+
const { stderr, stdout } = await execa(prettierBin, prettierArgs, {
|
|
104
|
+
env: { ...process.env },
|
|
105
|
+
});
|
|
106
|
+
if (stdout) {
|
|
107
|
+
this.log(stdout);
|
|
108
|
+
}
|
|
109
|
+
if (stderr) {
|
|
110
|
+
this.warn(stderr);
|
|
111
|
+
}
|
|
112
|
+
this.log(`Successfully formatted ${filePath}`);
|
|
113
|
+
}
|
|
114
|
+
detectPackageManager() {
|
|
115
|
+
// 检查项目根目录是否存在 pnpm-lock.yaml 来判断是否使用 pnpm
|
|
116
|
+
if (existsSync(join(process.cwd(), 'pnpm-lock.yaml'))) {
|
|
117
|
+
return 'pnpx';
|
|
118
|
+
}
|
|
119
|
+
// 检查是否存在 yarn.lock 来判断是否使用 yarn
|
|
120
|
+
if (existsSync(join(process.cwd(), 'yarn.lock'))) {
|
|
121
|
+
return 'yarn';
|
|
122
|
+
}
|
|
123
|
+
// 默认使用 npm
|
|
124
|
+
return 'npx';
|
|
125
|
+
}
|
|
126
|
+
findProjectPrettierConfig() {
|
|
127
|
+
const possibleConfigs = ['.prettierrc', '.prettierrc.json', '.prettierrc.yaml', '.prettierrc.yml', '.prettierrc.js'];
|
|
128
|
+
for (const configFile of possibleConfigs) {
|
|
129
|
+
if (existsSync(configFile)) {
|
|
130
|
+
return configFile;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
findProjectPrettierIgnore() {
|
|
136
|
+
const possibleIgnoreFiles = ['.prettierignore', '.gitignore'];
|
|
137
|
+
for (const ignoreFile of possibleIgnoreFiles) {
|
|
138
|
+
if (existsSync(ignoreFile)) {
|
|
139
|
+
return ignoreFile;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
// 替换默认参数中的插件路径
|
|
145
|
+
replacePluginArgs(defaultArgs, resolvedPluginPaths) {
|
|
146
|
+
const newArgs = [];
|
|
147
|
+
for (let i = 0; i < defaultArgs.length; i++) {
|
|
148
|
+
if (defaultArgs[i] === '--plugin' && i + 1 < defaultArgs.length) {
|
|
149
|
+
// 跳过这个 '--plugin' 标记和它的值,稍后替换
|
|
150
|
+
i++; // 跳过下一个值(插件名称)
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
newArgs.push(defaultArgs[i]);
|
|
154
|
+
}
|
|
155
|
+
// 添加解析后的插件路径
|
|
156
|
+
for (const pluginPath of resolvedPluginPaths) {
|
|
157
|
+
newArgs.push('--plugin', pluginPath);
|
|
158
|
+
}
|
|
159
|
+
return newArgs;
|
|
160
|
+
}
|
|
161
|
+
// 将插件名称转换为绝对路径
|
|
162
|
+
resolvePluginPaths(plugins, projectRoot) {
|
|
163
|
+
return plugins.map((plugin) => {
|
|
164
|
+
// 查找插件的实际路径
|
|
165
|
+
const pluginPath = join(projectRoot, 'node_modules', plugin.name, plugin.main);
|
|
166
|
+
if (existsSync(pluginPath)) {
|
|
167
|
+
return pluginPath;
|
|
168
|
+
}
|
|
169
|
+
// 如果插件路径不存在,则返回原始名称(让 prettier 自己处理)
|
|
170
|
+
return plugin.name;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -1,46 +1,76 @@
|
|
|
1
1
|
export const DEFAULT_ARGS = [
|
|
2
|
-
'--arrow-parens
|
|
3
|
-
'
|
|
4
|
-
'--
|
|
5
|
-
'
|
|
2
|
+
'--arrow-parens',
|
|
3
|
+
'always',
|
|
4
|
+
'--bracket-same-line',
|
|
5
|
+
'false',
|
|
6
|
+
'--object-wrap',
|
|
7
|
+
'preserve',
|
|
8
|
+
'--experimental-operator-position',
|
|
9
|
+
'end',
|
|
6
10
|
'--no-experimental-ternaries',
|
|
7
|
-
'--single-quote
|
|
8
|
-
'
|
|
9
|
-
'--
|
|
10
|
-
'
|
|
11
|
-
'--
|
|
12
|
-
'
|
|
13
|
-
'--
|
|
14
|
-
'
|
|
15
|
-
'--
|
|
16
|
-
'
|
|
17
|
-
'--
|
|
18
|
-
'
|
|
19
|
-
'--
|
|
20
|
-
'
|
|
21
|
-
'--
|
|
11
|
+
'--single-quote',
|
|
12
|
+
'false',
|
|
13
|
+
'--jsx-single-quote',
|
|
14
|
+
'false',
|
|
15
|
+
'--quote-props',
|
|
16
|
+
'as-needed',
|
|
17
|
+
'--trailing-comma',
|
|
18
|
+
'all',
|
|
19
|
+
'--single-attribute-per-line',
|
|
20
|
+
'false',
|
|
21
|
+
'--html-whitespace-sensitivity',
|
|
22
|
+
'css',
|
|
23
|
+
'--vue-indent-script-and-style',
|
|
24
|
+
'false',
|
|
25
|
+
'--prose-wrap',
|
|
26
|
+
'preserve',
|
|
27
|
+
'--end-of-line',
|
|
28
|
+
'lf',
|
|
29
|
+
'--insert-pragma',
|
|
30
|
+
'false',
|
|
31
|
+
'--print-width',
|
|
32
|
+
'80',
|
|
33
|
+
'--require-pragma',
|
|
34
|
+
'false',
|
|
35
|
+
'--tab-width',
|
|
36
|
+
'2',
|
|
37
|
+
'--use-tabs',
|
|
38
|
+
'false',
|
|
39
|
+
'--embedded-language-formatting',
|
|
40
|
+
'auto',
|
|
22
41
|
// plugins
|
|
23
|
-
'--plugin
|
|
24
|
-
'
|
|
25
|
-
'--plugin
|
|
26
|
-
'
|
|
42
|
+
'--plugin',
|
|
43
|
+
'@prettier/plugin-xml',
|
|
44
|
+
'--plugin',
|
|
45
|
+
'prettier-plugin-toml',
|
|
46
|
+
'--plugin',
|
|
47
|
+
'prettier-plugin-sh',
|
|
48
|
+
'--plugin',
|
|
49
|
+
'prettier-plugin-nginx',
|
|
27
50
|
// xml
|
|
28
|
-
'--xml-whitespace-sensitivity
|
|
29
|
-
'
|
|
30
|
-
'--xml-
|
|
51
|
+
'--xml-whitespace-sensitivity',
|
|
52
|
+
'strict',
|
|
53
|
+
'--xml-sort-attributes-by-key',
|
|
54
|
+
'true',
|
|
55
|
+
'--xml-self-closing-space',
|
|
56
|
+
'true',
|
|
31
57
|
// toml
|
|
32
|
-
'--indent-entries
|
|
33
|
-
'
|
|
58
|
+
'--indent-entries',
|
|
59
|
+
'true',
|
|
60
|
+
'--reorder-keys',
|
|
61
|
+
'true',
|
|
34
62
|
// nginx
|
|
35
|
-
'--wrap-parameters
|
|
36
|
-
'
|
|
63
|
+
'--wrap-parameters',
|
|
64
|
+
'false',
|
|
65
|
+
'--continuation-indent',
|
|
66
|
+
'2',
|
|
37
67
|
];
|
|
38
68
|
// 默认的 Prettier 插件列表
|
|
39
69
|
export const DEFAULT_PLUGINS = [
|
|
40
|
-
'@prettier/plugin-xml',
|
|
41
|
-
'prettier-plugin-toml',
|
|
42
|
-
'prettier-plugin-
|
|
43
|
-
'prettier-plugin-
|
|
70
|
+
{ main: 'src/plugin.js', name: '@prettier/plugin-xml' },
|
|
71
|
+
{ main: 'lib/index.cjs', name: 'prettier-plugin-toml' },
|
|
72
|
+
{ main: 'lib/index.cjs', name: 'prettier-plugin-sh' },
|
|
73
|
+
{ main: 'dist/index', name: 'prettier-plugin-nginx' },
|
|
44
74
|
];
|
|
45
75
|
// 默认的忽略模式
|
|
46
76
|
export const DEFAULT_IGNORE_PATTERNS = [
|
package/oclif.manifest.json
CHANGED
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"world.js"
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
|
-
"
|
|
67
|
+
"pr": {
|
|
68
68
|
"aliases": [],
|
|
69
69
|
"args": {
|
|
70
70
|
"filePath": {
|
|
@@ -81,18 +81,19 @@
|
|
|
81
81
|
"flags": {
|
|
82
82
|
"config": {
|
|
83
83
|
"char": "c",
|
|
84
|
-
"description": "
|
|
84
|
+
"description": "built_in:使用内置规则(默认值), 传入路径则是使用自定义配置, auto:自动检测config file",
|
|
85
85
|
"name": "config",
|
|
86
86
|
"required": false,
|
|
87
|
+
"default": "built_in",
|
|
87
88
|
"hasDynamicHelp": false,
|
|
88
89
|
"multiple": false,
|
|
89
90
|
"type": "option"
|
|
90
91
|
},
|
|
91
92
|
"ignore": {
|
|
92
|
-
"
|
|
93
|
-
"description": "Prettier ignore file path",
|
|
93
|
+
"description": "built_in:使用内置规则(默认值), 传入路径则是使用自定义规则, auto:自动检测ignore file",
|
|
94
94
|
"name": "ignore",
|
|
95
95
|
"required": false,
|
|
96
|
+
"default": "built_in",
|
|
96
97
|
"hasDynamicHelp": false,
|
|
97
98
|
"multiple": false,
|
|
98
99
|
"type": "option"
|
|
@@ -100,7 +101,7 @@
|
|
|
100
101
|
},
|
|
101
102
|
"hasDynamicHelp": false,
|
|
102
103
|
"hiddenAliases": [],
|
|
103
|
-
"id": "
|
|
104
|
+
"id": "pr",
|
|
104
105
|
"pluginAlias": "meocli",
|
|
105
106
|
"pluginName": "meocli",
|
|
106
107
|
"pluginType": "core",
|
|
@@ -110,10 +111,10 @@
|
|
|
110
111
|
"relativePath": [
|
|
111
112
|
"dist",
|
|
112
113
|
"commands",
|
|
113
|
-
"
|
|
114
|
+
"pr",
|
|
114
115
|
"index.js"
|
|
115
116
|
]
|
|
116
117
|
}
|
|
117
118
|
},
|
|
118
|
-
"version": "0.0.
|
|
119
|
+
"version": "0.0.5"
|
|
119
120
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meocli",
|
|
3
3
|
"description": "A new CLI generated with oclif",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"author": "meme2046",
|
|
6
6
|
"bin": {
|
|
7
7
|
"me": "./bin/run.js"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"@oclif/plugin-help": "^6",
|
|
13
13
|
"@oclif/plugin-plugins": "^5",
|
|
14
14
|
"@prettier/plugin-xml": "^3.4.2",
|
|
15
|
+
"execa": "^9.6.1",
|
|
15
16
|
"prettier": "^3.7.4",
|
|
16
17
|
"prettier-plugin-nginx": "^1.0.3",
|
|
17
18
|
"prettier-plugin-sh": "^0.18.0",
|
|
@@ -67,6 +68,8 @@
|
|
|
67
68
|
"repository": "meme2046/meocli",
|
|
68
69
|
"types": "dist/index.d.ts",
|
|
69
70
|
"scripts": {
|
|
71
|
+
"lk": "pnpm link --global",
|
|
72
|
+
"ulk": "pnpm unlink --global meocli",
|
|
70
73
|
"dev": "node --no-deprecation --no-warnings --loader ts-node/esm --disable-warning=ExperimentalWarning bin/dev.js",
|
|
71
74
|
"prod": "node bin/run.js",
|
|
72
75
|
"prettier": "prettier",
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
import { spawn } from 'node:child_process';
|
|
3
|
-
import { existsSync } from 'node:fs';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { DEFAULT_ARGS } from '../../consts/prettierrc.js';
|
|
6
|
-
export default class Prettier extends Command {
|
|
7
|
-
static args = {
|
|
8
|
-
filePath: Args.string({
|
|
9
|
-
description: 'file path that need to be formatted by Prettier',
|
|
10
|
-
required: true,
|
|
11
|
-
}),
|
|
12
|
-
};
|
|
13
|
-
static description = 'Use Prettier to format file';
|
|
14
|
-
static examples = [
|
|
15
|
-
'<%= config.bin %> <%= command.id %> ./tests/test.json',
|
|
16
|
-
'<%= config.bin %> <%= command.id %> ./src/file.ts --config ./.prettierrc.yaml',
|
|
17
|
-
];
|
|
18
|
-
static flags = {
|
|
19
|
-
config: Flags.string({
|
|
20
|
-
char: 'c',
|
|
21
|
-
// default: './src/files/.prettierrc.yaml',
|
|
22
|
-
description: 'Prettier config file path',
|
|
23
|
-
required: false,
|
|
24
|
-
}),
|
|
25
|
-
ignore: Flags.string({
|
|
26
|
-
char: 'i',
|
|
27
|
-
// default: './src/files/.prettierignore',
|
|
28
|
-
description: 'Prettier ignore file path',
|
|
29
|
-
required: false,
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
|
-
async run() {
|
|
33
|
-
const { args, flags } = await this.parse(Prettier);
|
|
34
|
-
const { filePath } = args;
|
|
35
|
-
const { config, ignore } = flags;
|
|
36
|
-
// 检查文件是否存在
|
|
37
|
-
if (!existsSync(filePath)) {
|
|
38
|
-
this.error(`file 『${filePath}』 not found`);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
// 检测当前使用的包管理器
|
|
42
|
-
const packageManager = this.detectPackageManager();
|
|
43
|
-
// 根据包管理器类型构建参数
|
|
44
|
-
let prettierArgs = ['prettier', '--write', filePath];
|
|
45
|
-
if (config && existsSync(config)) {
|
|
46
|
-
prettierArgs.push(`--config=${config}`);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
// 否则尝试查找项目中的配置文件
|
|
50
|
-
const projectConfig = this.findProjectPrettierConfig();
|
|
51
|
-
if (projectConfig) {
|
|
52
|
-
prettierArgs.push(`--config=${projectConfig}`);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
prettierArgs = [...prettierArgs, ...DEFAULT_ARGS];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (ignore && existsSync(ignore)) {
|
|
59
|
-
prettierArgs.push(`--ignore-path=${ignore}`);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const projectIgnore = this.findProjectPrettierIgnore();
|
|
63
|
-
if (projectIgnore) {
|
|
64
|
-
prettierArgs.push(`--ignore-path=${projectIgnore}`);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
// 如果没有找到项目 ignore 文件,跳过此参数
|
|
68
|
-
// Prettier 会使用默认的忽略规则
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
this.log(JSON.stringify(prettierArgs));
|
|
72
|
-
// this.log(`Formatting file: ${filePath}`)
|
|
73
|
-
// 返回一个 Promise 以等待子进程完成
|
|
74
|
-
await new Promise((resolve, reject) => {
|
|
75
|
-
const prettierProcess = spawn(packageManager, prettierArgs, {
|
|
76
|
-
env: { ...process.env }, // 确保子进程继承当前环境变量
|
|
77
|
-
shell: false, // 设置为 false 以避免安全警告
|
|
78
|
-
// stdio: 'inherit',
|
|
79
|
-
stdio: 'pipe', // 更改为 pipe 以便捕获输出
|
|
80
|
-
});
|
|
81
|
-
prettierProcess.on('close', (code) => {
|
|
82
|
-
if (code === 0) {
|
|
83
|
-
this.log(`Successfully formatted ${filePath}`);
|
|
84
|
-
resolve(null);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
reject(new Error(`Prettier exited with code ${code}`));
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
prettierProcess.on('error', (error) => {
|
|
91
|
-
reject(error);
|
|
92
|
-
});
|
|
93
|
-
}).catch((error) => {
|
|
94
|
-
this.error(`Error executing prettier: ${error.message}`);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
detectPackageManager() {
|
|
98
|
-
// 检查项目根目录是否存在 pnpm-lock.yaml 来判断是否使用 pnpm
|
|
99
|
-
if (existsSync(join(process.cwd(), 'pnpm-lock.yaml'))) {
|
|
100
|
-
return 'pnpx';
|
|
101
|
-
}
|
|
102
|
-
// 检查是否存在 yarn.lock 来判断是否使用 yarn
|
|
103
|
-
if (existsSync(join(process.cwd(), 'yarn.lock'))) {
|
|
104
|
-
return 'yarn';
|
|
105
|
-
}
|
|
106
|
-
// 默认使用 npm
|
|
107
|
-
return 'npx';
|
|
108
|
-
}
|
|
109
|
-
findProjectPrettierConfig() {
|
|
110
|
-
const possibleConfigs = [
|
|
111
|
-
'./.prettierrc',
|
|
112
|
-
'./.prettierrc.json',
|
|
113
|
-
'./.prettierrc.yaml',
|
|
114
|
-
'./.prettierrc.yml',
|
|
115
|
-
'./.prettierrc.js',
|
|
116
|
-
];
|
|
117
|
-
for (const configFile of possibleConfigs) {
|
|
118
|
-
if (existsSync(configFile)) {
|
|
119
|
-
return configFile;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
findProjectPrettierIgnore() {
|
|
125
|
-
const possibleIgnoreFiles = [
|
|
126
|
-
'./.prettierignore',
|
|
127
|
-
// './.gitignore'
|
|
128
|
-
];
|
|
129
|
-
for (const ignoreFile of possibleIgnoreFiles) {
|
|
130
|
-
if (existsSync(ignoreFile)) {
|
|
131
|
-
return ignoreFile;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
}
|