Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(remote): download and extract zip file if the remote is a GitHub URL #357

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"iconv-lite": "^0.6.3",
"istextorbinary": "^9.5.0",
"jschardet": "^3.1.4",
"jszip": "^3.10.1",
"log-update": "^6.1.0",
"minimatch": "^10.0.1",
"picocolors": "^1.1.1",
Expand Down
41 changes: 32 additions & 9 deletions src/cli/actions/remoteAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,26 @@
import GitUrlParse, { type GitUrl } from 'git-url-parse';
import pc from 'picocolors';
import { execGitShallowClone, isGitInstalled } from '../../core/file/gitCommand.js';
import { downloadGitHubZip, isGitHubUrlOrShorthand, validShorthandRegex } from '../../core/file/githubZipDownload.js';
import { RepomixError } from '../../shared/errorHandle.js';
import { logger } from '../../shared/logger.js';
import Spinner from '../cliSpinner.js';
import type { CliOptions } from '../types.js';
import { type DefaultActionRunnerResult, runDefaultAction } from './defaultAction.js';

interface IGitUrl extends GitUrl {
commit: string | undefined;
}

export const runRemoteAction = async (
repoUrl: string,
cliOptions: CliOptions,
deps = {
isGitInstalled,
execGitShallowClone,
downloadGitHubZip,
runDefaultAction,
isGitHubUrlOrShorthand,
},
): Promise<DefaultActionRunnerResult> => {
if (!(await deps.isGitInstalled())) {
Expand All @@ -33,19 +38,39 @@
try {
spinner.start();

// Clone the repository
await cloneRepository(parsedFields.repoUrl, tempDirPath, cliOptions.remoteBranch || parsedFields.remoteBranch, {
execGitShallowClone: deps.execGitShallowClone,
});
// Try GitHub zip download first for GitHub URLs or shorthand format
if (deps.isGitHubUrlOrShorthand(repoUrl)) {
try {
spinner.update('Downloading repository zip...');
await deps.downloadGitHubZip(
repoUrl, // Pass original URL/shorthand - parseGitHubUrl will handle both formats
tempDirPath,
cliOptions.remoteBranch || parsedFields.remoteBranch,
);
spinner.succeed('Repository downloaded successfully!');
} catch (error) {
logger.debug(`GitHub zip download failed, falling back to git clone: ${error}`);
spinner.update('Falling back to git clone...');
await cloneRepository(parsedFields.repoUrl, tempDirPath, cliOptions.remoteBranch || parsedFields.remoteBranch, {
execGitShallowClone: deps.execGitShallowClone,
});
spinner.succeed('Repository cloned successfully!');
}
} else {
// Use git clone for non-GitHub URLs
await cloneRepository(parsedFields.repoUrl, tempDirPath, cliOptions.remoteBranch || parsedFields.remoteBranch, {
execGitShallowClone: deps.execGitShallowClone,
});
spinner.succeed('Repository cloned successfully!');
}

spinner.succeed('Repository cloned successfully!');
logger.log('');

// Run the default action on the cloned repository
// Run the default action on the downloaded repository
result = await deps.runDefaultAction([tempDirPath], tempDirPath, cliOptions);
await copyOutputToCurrentDirectory(tempDirPath, process.cwd(), result.config.output.filePath);
} catch (error) {
spinner.fail('Error during repository cloning. cleanup...');
spinner.fail('Error during repository download/clone. cleanup...');

Check warning on line 73 in src/cli/actions/remoteAction.ts

View check run for this annotation

Codecov / codecov/patch

src/cli/actions/remoteAction.ts#L73

Added line #L73 was not covered by tests
throw error;
} finally {
// Cleanup the temporary directory
Expand All @@ -56,8 +81,6 @@
};

// Check the short form of the GitHub URL. e.g. yamadashy/repomix
const VALID_NAME_PATTERN = '[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?';
const validShorthandRegex = new RegExp(`^${VALID_NAME_PATTERN}/${VALID_NAME_PATTERN}$`);
export const isValidShorthand = (remoteValue: string): boolean => {
return validShorthandRegex.test(remoteValue);
};
Expand Down
Loading
Loading