From 5bda30465ab2e7900d7339d56c94d0063c989f59 Mon Sep 17 00:00:00 2001 From: ddreamboy Date: Tue, 31 Dec 2024 21:31:47 +0300 Subject: [PATCH 1/2] Add support for local repositories --- index.js | 113 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 39 deletions(-) diff --git a/index.js b/index.js index c14f5f2..ee18b7a 100755 --- a/index.js +++ b/index.js @@ -32,22 +32,24 @@ import { promisify } from 'util'; const execAsync = promisify(exec); -// CLI help text with usage instructions and examples +// Обновленный текст помощи с информацией о локальных репозиториях const helpText = ` ${chalk.bold('Usage')} - $ git2txt + $ git2txt ${chalk.bold('Options')} --output, -o Specify output file path --threshold, -t Set file size threshold in MB (default: 0.5) --include-all Include all files regardless of size or type + --local Process local repository path --debug Enable debug mode with verbose logging --help Show help --version Show version ${chalk.bold('Examples')} $ git2txt https://github.com/username/repository - $ git2txt https://github.com/username/repository --output=output.txt + $ git2txt /path/to/local/repo --local + $ git2txt ./my-repo --local --output=output.txt `; /** @@ -80,6 +82,10 @@ export const cli = meow(helpText, { type: 'boolean', default: false }, + local: { + type: 'boolean', + default: false + }, debug: { type: 'boolean', default: false @@ -120,22 +126,48 @@ function normalizeGitHubUrl(url) { } /** - * Validates the command line input - * @param {string[]} input - Command line arguments - * @returns {Promise} Validated repository URL - * @throws {Error} If input is missing or invalid + * Проверяет существование локального репозитория + * @param {string} path - Путь к локальному репозиторию + * @returns {Promise} Существует ли репозиторий */ -export async function validateInput(input) { +async function validateLocalRepo(repoPath) { + try { + const stats = await fs.stat(repoPath); + const gitPath = path.join(repoPath, '.git'); + const gitStats = await fs.stat(gitPath); + + return stats.isDirectory() && gitStats.isDirectory(); + } catch (error) { + return false; + } +} + +/** + * Валидирует входные данные с учетом локальных репозиториев + * @param {string[]} input - Аргументы командной строки + * @param {Object} flags - Флаги CLI + * @returns {Promise} Объект с валидированными данными + */ +export async function validateInput(input, flags) { if (!input || input.length === 0) { - throw new Error('Repository URL is required'); + throw new Error('Repository URL or path is required'); } - const url = input[0]; - if (!url.includes('github.com') && !url.match(/^[\w-]+\/[\w-]+$/)) { - throw new Error('Only GitHub repositories are supported'); + const source = input[0]; + + if (flags.local) { + const isValidRepo = await validateLocalRepo(source); + if (!isValidRepo) { + throw new Error('Invalid local repository path. Make sure it\'s a Git repository.'); + } + return { type: 'local', path: source }; + } + + if (!source.includes('github.com') && !source.match(/^[\w-]+\/[\w-]+$/)) { + throw new Error('Only GitHub repositories or local paths (with --local flag) are supported'); } - return url; + return { type: 'remote', url: source }; } /** @@ -340,37 +372,40 @@ export async function cleanup(directory) { * @returns {Promise} */ export async function main() { - let tempDir; try { - const url = await validateInput(cli.input); - if (process.env.NODE_ENV !== 'test') { - const result = await downloadRepository(url); - tempDir = result.tempDir; - - const outputPath = cli.flags.output || `${result.repoName}.txt`; - const content = await processFiles(tempDir, { - threshold: cli.flags.threshold, - includeAll: cli.flags.includeAll - }); - - if (!content) { - throw new Error('No content was generated from the repository'); - } + const result = await validateInput(cli.input, cli.flags); + let targetDir; + let repoName; - await writeOutput(content, outputPath); - } - } catch (error) { - if (process.env.NODE_ENV === 'test') { - throw error; + if (result.type === 'local') { + targetDir = result.path; + repoName = path.basename(result.path); } else { - console.error(chalk.red('\nAn unexpected error occurred:')); - console.error(error.message || error); - exit(1); + const downloadResult = await downloadRepository(result.url); + targetDir = downloadResult.tempDir; + repoName = downloadResult.repoName; + } + + const outputPath = cli.flags.output || `${repoName}.txt`; + const content = await processFiles(targetDir, { + threshold: cli.flags.threshold, + includeAll: cli.flags.includeAll + }); + + if (!content) { + throw new Error('No content was generated from the repository'); } - } finally { - if (tempDir) { - await cleanup(tempDir); + + await writeOutput(content, outputPath); + + // Очищаем временные файлы только для удаленных репозиториев + if (result.type === 'remote') { + await cleanup(targetDir); } + } catch (error) { + console.error(chalk.red('\nAn error occurred:')); + console.error(error.message || error); + process.exit(1); } } From 3a071ee56c37730af95765682bccdc6b506930b4 Mon Sep 17 00:00:00 2001 From: ddreamboy Date: Tue, 31 Dec 2024 21:38:42 +0300 Subject: [PATCH 2/2] update README.md --- README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 601c47d..7363245 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Convert GitHub repositories to text files with ease. This CLI tool downloads a r ## Features - 📥 Download any public GitHub repository +- 🔒 Process local Git repositories (including private ones) - 📝 Convert repository contents to a single text file - ⚡ Automatic binary file exclusion - 🔧 Configurable file size threshold @@ -31,6 +32,9 @@ git2txt username/repository # SSH format git2txt git@github.com:username/repository + +# Local repository path (requires --local flag) +git2txt /path/to/local/repo --local ``` ### URL Format Support @@ -42,6 +46,7 @@ The tool accepts these GitHub repository URL formats: - SSH URLs: `git@github.com:username/repository` - URLs with or without `.git` suffix - URLs with or without trailing slashes +- Local paths with `--local` flag: `/path/to/repo` or `./relative/path` ### Options @@ -49,6 +54,7 @@ The tool accepts these GitHub repository URL formats: --output, -o Specify output file path (default: repo-name.txt) --threshold, -t Set file size threshold in MB (default: 0.1) --include-all Include all files regardless of size or type +--local Process local repository path --debug Enable debug mode with verbose logging --help Show help --version Show version @@ -78,6 +84,15 @@ git2txt username/repository --include-all # Enable debug output git2txt username/repository --debug + +# Using local repository path +git2txt /path/to/local/repo --local + +# Local repository with custom output +git2txt ./my-repo --local --output=output.txt + +# Local repository with custom threshold +git2txt ./my-repo --local --threshold=2 ``` ## Default Behavior @@ -115,4 +130,4 @@ Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) ## License -MIT +MIT \ No newline at end of file