feat: документация с алиасом create и корректные примеры
- Обновлены примеры в README и FEATURES с использованием алиаса create - Исправлены подсказки help на основной бин gromlab-create - Возвращены внутренние вызовы автодополнения на gromlab-create
This commit is contained in:
21
README.md
21
README.md
@@ -15,17 +15,28 @@ npm i -g @gromlab/create
|
||||
|
||||
## Автодополнение
|
||||
|
||||
Сгенерируйте скрипт и подключите его в оболочке:
|
||||
Установка вместе с автодополнением (одной командой):
|
||||
|
||||
**bash**
|
||||
```bash
|
||||
gromlab-create completion --shell bash
|
||||
npm i -g @gromlab/create && create install-autocomplete --shell bash && source ~/.bashrc
|
||||
```
|
||||
|
||||
**zsh**
|
||||
```bash
|
||||
npm i -g @gromlab/create && create install-autocomplete --shell zsh && source ~/.zshrc
|
||||
```
|
||||
|
||||
**fish**
|
||||
```bash
|
||||
npm i -g @gromlab/create && create install-autocomplete --shell fish && exec fish
|
||||
```
|
||||
|
||||
|
||||
## Использование
|
||||
|
||||
```bash
|
||||
npx @gromlab/create <шаблон> <имя> [путь] [опции]
|
||||
create <шаблон> <имя> [путь] [опции]
|
||||
```
|
||||
|
||||
Если `[путь]` не указан, файлы создаются в директории, где запущен CLI.
|
||||
@@ -34,10 +45,10 @@ npx @gromlab/create <шаблон> <имя> [путь] [опции]
|
||||
|
||||
```bash
|
||||
# Создать компонент из шаблона
|
||||
npx @gromlab/create component Button
|
||||
create component Button
|
||||
|
||||
# Указать папку вывода позиционно
|
||||
npx @gromlab/create component Button src/components
|
||||
create component Button src/components
|
||||
```
|
||||
|
||||
## Шаблоны
|
||||
|
||||
@@ -42,9 +42,10 @@
|
||||
|
||||
## Автодополнение
|
||||
|
||||
- Генерация скрипта автодополнения для bash/zsh/fish: `gromlab-create completion --shell <shell>`.
|
||||
- Генерация скрипта автодополнения для bash/zsh/fish: `create completion --shell <shell>`.
|
||||
- Автодополнение доступно только для глобальной установки CLI.
|
||||
- Автодополнение шаблонов из ближайшей `.templates/` (по дереву вверх) и переменных `--<var>` выбранного шаблона (кроме `name`).
|
||||
- Команда `install-autocomplete` устанавливает автодополнение в конфигурацию оболочки (bash/zsh) или файл fish‑completions.
|
||||
|
||||
## Обновления CLI
|
||||
|
||||
@@ -62,8 +63,7 @@
|
||||
|
||||
## Бины
|
||||
|
||||
- Основной бин: `gromlab-create`.
|
||||
- Дополнительный алиас: `create`.
|
||||
- Основной бин: `gromlab-create` (в примерах используется алиас `create`).
|
||||
|
||||
## Служебные команды
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@gromlab/create",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"description": "Template-based file generator CLI",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ParsedArgs } from './types';
|
||||
export function printHelp() {
|
||||
const lines = [
|
||||
'Использование:',
|
||||
' npx @gromlab/create <шаблон> <имя> [путь] [опции]',
|
||||
' gromlab-create <шаблон> <имя> [путь] [опции]',
|
||||
'',
|
||||
'Аргументы:',
|
||||
' <шаблон> Имя шаблона',
|
||||
@@ -12,6 +12,7 @@ export function printHelp() {
|
||||
'',
|
||||
'Команды:',
|
||||
' completion --shell <bash|zsh|fish> Сгенерировать скрипт автодополнения',
|
||||
' install-autocomplete [--shell <bash|zsh|fish>] Установить автодополнение',
|
||||
'',
|
||||
'Опции:',
|
||||
' --<var> <value> Переменная шаблона (поддерживается любой --key <value>)',
|
||||
@@ -20,8 +21,8 @@ export function printHelp() {
|
||||
' -h, --help Показать эту справку',
|
||||
'',
|
||||
'Примеры:',
|
||||
' npx @gromlab/create component Button',
|
||||
' npx @gromlab/create component Button src/components'
|
||||
' gromlab-create component Button',
|
||||
' gromlab-create component Button src/components'
|
||||
];
|
||||
console.log(lines.join('\n'));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { collectTemplateVariables, listTemplateNames } from './templateUtils';
|
||||
import { detectRunMode } from './runtime';
|
||||
|
||||
const BIN_NAMES = ['gromlab-create', 'create'];
|
||||
const COMPLETION_BLOCK_START = '# gromlab-create completion start';
|
||||
const COMPLETION_BLOCK_END = '# gromlab-create completion end';
|
||||
|
||||
function findNearestTemplatesDir(startDir: string): string | undefined {
|
||||
let current = path.resolve(startDir);
|
||||
@@ -205,9 +207,69 @@ function resolveShell(args: string[]): string | undefined {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
function normalizeShellName(shell?: string): string | undefined {
|
||||
if (!shell) return undefined;
|
||||
let normalized = shell.trim().toLowerCase();
|
||||
if (normalized === 'zh') normalized = 'zsh';
|
||||
if (normalized === 'bash' || normalized === 'zsh' || normalized === 'fish') return normalized;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function detectShellFromEnv(): string | undefined {
|
||||
const envShell = process.env.SHELL ?? '';
|
||||
const base = path.basename(envShell).toLowerCase();
|
||||
if (base === 'bash' || base === 'zsh' || base === 'fish') return base;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function printCompletionUsage() {
|
||||
console.log('Использование:');
|
||||
console.log(' gromlab-create completion --shell <bash|zsh|fish>');
|
||||
console.log(' gromlab-create install-autocomplete [--shell <bash|zsh|fish>]');
|
||||
}
|
||||
|
||||
function escapeRegExp(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
function installForBashOrZsh(shell: 'bash' | 'zsh') {
|
||||
const home = process.env.HOME ?? '';
|
||||
const rcFile = shell === 'bash'
|
||||
? path.join(home, '.bashrc')
|
||||
: path.join(home, '.zshrc');
|
||||
const sourceLine = `source <(gromlab-create completion --shell ${shell})`;
|
||||
const block = `${COMPLETION_BLOCK_START}\n${sourceLine}\n${COMPLETION_BLOCK_END}`;
|
||||
const start = escapeRegExp(COMPLETION_BLOCK_START);
|
||||
const end = escapeRegExp(COMPLETION_BLOCK_END);
|
||||
const blockRegex = new RegExp(`${start}[\\s\\S]*?${end}`, 'm');
|
||||
|
||||
let content = '';
|
||||
try {
|
||||
if (fs.existsSync(rcFile)) {
|
||||
content = fs.readFileSync(rcFile, 'utf8');
|
||||
}
|
||||
} catch {
|
||||
content = '';
|
||||
}
|
||||
|
||||
if (blockRegex.test(content)) {
|
||||
content = content.replace(blockRegex, block);
|
||||
} else {
|
||||
const prefix = content.length > 0 && !content.endsWith('\n') ? '\n' : '';
|
||||
content = `${content}${prefix}${block}\n`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(rcFile, content, 'utf8');
|
||||
console.log(`Автодополнение установлено в ${rcFile}`);
|
||||
}
|
||||
|
||||
function installForFish() {
|
||||
const home = process.env.HOME ?? '';
|
||||
const dir = path.join(home, '.config', 'fish', 'completions');
|
||||
const filePath = path.join(dir, 'gromlab-create.fish');
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
fs.writeFileSync(filePath, buildFishCompletion(), 'utf8');
|
||||
console.log(`Автодополнение установлено в ${filePath}`);
|
||||
}
|
||||
|
||||
export function handleInternalCommand(args: string[], cwd: string = process.cwd()): boolean {
|
||||
@@ -234,19 +296,17 @@ export function handleInternalCommand(args: string[], cwd: string = process.cwd(
|
||||
return true;
|
||||
}
|
||||
|
||||
const shell = resolveShell(rest);
|
||||
const shell = normalizeShellName(resolveShell(rest));
|
||||
if (!shell) {
|
||||
printCompletionUsage();
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
let normalized = shell.trim().toLowerCase();
|
||||
if (normalized === 'zh') normalized = 'zsh';
|
||||
let script = '';
|
||||
if (normalized === 'bash') script = buildBashCompletion();
|
||||
if (normalized === 'zsh') script = buildZshCompletion();
|
||||
if (normalized === 'fish') script = buildFishCompletion();
|
||||
if (shell === 'bash') script = buildBashCompletion();
|
||||
if (shell === 'zsh') script = buildZshCompletion();
|
||||
if (shell === 'fish') script = buildFishCompletion();
|
||||
|
||||
if (!script) {
|
||||
console.error('Неизвестный shell. Доступно: bash, zsh, fish.');
|
||||
@@ -258,5 +318,34 @@ export function handleInternalCommand(args: string[], cwd: string = process.cwd(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command === 'install-autocomplete' || command === 'install-shell') {
|
||||
if (detectRunMode() !== 'global') {
|
||||
console.error('Автодополнение доступно только для глобальной установки CLI.');
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const explicitShell = normalizeShellName(resolveShell(rest));
|
||||
const shell = explicitShell ?? detectShellFromEnv();
|
||||
if (!shell) {
|
||||
console.error('Не удалось определить shell. Укажите --shell <bash|zsh|fish>.');
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shell === 'bash' || shell === 'zsh') {
|
||||
installForBashOrZsh(shell);
|
||||
return true;
|
||||
}
|
||||
if (shell === 'fish') {
|
||||
installForFish();
|
||||
return true;
|
||||
}
|
||||
|
||||
console.error('Неизвестный shell. Доступно: bash, zsh, fish.');
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user