Skip to content

Commit

Permalink
A litle refactoring and more tests for url parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
huy-trn committed Feb 5, 2025
1 parent 43d8a43 commit c75ea41
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 28 deletions.
58 changes: 38 additions & 20 deletions src/cli/actions/remoteAction.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import * as fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import GitUrlParse from 'git-url-parse';
import GitUrlParse, { type GitUrl } from 'git-url-parse';
import pc from 'picocolors';
import { execGitShallowClone, isGitInstalled } from '../../core/file/gitCommand.js';
import { RepomixError } from '../../shared/errorHandle.js';
import { logger } from '../../shared/logger.js';
import type { CliOptions } from '../cliRun.js';
import Spinner from '../cliSpinner.js';
import { type DefaultActionRunnerResult, runDefaultAction } from './defaultAction.js';

interface CorrectedGitUrl extends GitUrl {
commit: string | undefined;
}
export const runRemoteAction = async (
repoUrl: string,
options: CliOptions,
Expand Down Expand Up @@ -67,31 +69,47 @@ export const isValidShorthand = (remoteValue: string): boolean => {
};

export const parseRemoteValue = (remoteValue: string): { repoUrl: string; remoteBranch: string | undefined } => {
if (isValidShorthand(remoteValue)) {
logger.trace(`Formatting GitHub shorthand: ${remoteValue}`);
return {
repoUrl: `https://github.com/${remoteValue}.git`,
remoteBranch: undefined,
};
}

try {
let repoUrl: string;
if (isValidShorthand(remoteValue)) {
logger.trace(`Formatting GitHub shorthand: ${remoteValue}`);
repoUrl = `https://github.com/${remoteValue}.git`;
return {
repoUrl: repoUrl,
remoteBranch: undefined,
};
}
const parsedFields = GitUrlParse(remoteValue);
console.log(parsedFields);
const ownerSlashName =

// This will make parsedFields.toString() automatically append '.git' to the returned url
parsedFields.git_suffix = true;

const ownerSlashRepo =
parsedFields.full_name.split('/').length > 1 ? parsedFields.full_name.split('/').slice(-2).join('/') : '';

if (ownerSlashName !== '' && !isValidShorthand(ownerSlashName)) {
if (ownerSlashRepo !== '' && !isValidShorthand(ownerSlashRepo)) {
throw new RepomixError('Invalid owner/repo in repo URL');
}
const remoteBranch = parsedFields.ref !== '' ? parsedFields.ref : undefined;
repoUrl = parsedFields.toString(parsedFields.protocol);
if (parsedFields.protocol === 'https' && !repoUrl.endsWith('.git')) {
logger.trace(`Adding .git to HTTPS URL: ${repoUrl}`);
repoUrl = `${repoUrl}.git`;

const repoUrl = parsedFields.toString(parsedFields.protocol);

if (parsedFields.ref) {
return {
repoUrl: repoUrl,
remoteBranch: parsedFields.ref,
};
}

if ((parsedFields as CorrectedGitUrl).commit) {
return {
repoUrl: repoUrl,
remoteBranch: (parsedFields as CorrectedGitUrl).commit,
};
}
return { repoUrl, remoteBranch };

return {
repoUrl: repoUrl,
remoteBranch: undefined,
};
} catch (error) {
throw new RepomixError('Invalid remote repository URL or repository shorthand (owner/repo)');
}
Expand Down
63 changes: 55 additions & 8 deletions tests/cli/actions/remoteAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,69 @@ describe('remoteAction functions', () => {
});
});

describe('formatGitUrl', () => {
describe('parseRemoteValue', () => {
test('should convert GitHub shorthand to full URL', () => {
expect(parseRemoteValue('user/repo').repoUrl).toBe('https://github.com/user/repo.git');
expect(parseRemoteValue('user-name/repo-name').repoUrl).toBe('https://github.com/user-name/repo-name.git');
expect(parseRemoteValue('user_name/repo_name').repoUrl).toBe('https://github.com/user_name/repo_name.git');
expect(parseRemoteValue('a.b/a-b_c').repoUrl).toBe('https://github.com/a.b/a-b_c.git');
expect(parseRemoteValue('user/repo')).toEqual({
repoUrl: 'https://github.com/user/repo.git',
remoteBranch: undefined,
});
expect(parseRemoteValue('user-name/repo-name')).toEqual({
repoUrl: 'https://github.com/user-name/repo-name.git',
remoteBranch: undefined,
});
expect(parseRemoteValue('user_name/repo_name')).toEqual({
repoUrl: 'https://github.com/user_name/repo_name.git',
remoteBranch: undefined,
});
expect(parseRemoteValue('a.b/a-b_c')).toEqual({
repoUrl: 'https://github.com/a.b/a-b_c.git',
remoteBranch: undefined,
});
});

test('should handle HTTPS URLs', () => {
expect(parseRemoteValue('https://github.com/user/repo').repoUrl).toBe('https://github.com/user/repo.git');
expect(parseRemoteValue('https://github.com/user/repo.git').repoUrl).toBe('https://github.com/user/repo.git');
expect(parseRemoteValue('https://github.com/user/repo')).toEqual({
repoUrl: 'https://github.com/user/repo.git',
remoteBranch: undefined,
});
expect(parseRemoteValue('https://github.com/user/repo.git')).toEqual({
repoUrl: 'https://github.com/user/repo.git',
remoteBranch: undefined,
});
});

test('should not modify SSH URLs', () => {
const sshUrl = 'git@github.com:user/repo.git';
expect(parseRemoteValue(sshUrl).repoUrl).toBe(sshUrl);
const parsed = parseRemoteValue(sshUrl);
expect(parsed).toEqual({
repoUrl: sshUrl,
remoteBranch: undefined,
});
});

test('should get correct branch name from url', () => {
expect(parseRemoteValue('https://github.com/username/repo/tree/branchname')).toEqual({
repoUrl: 'https://github.com/username/repo.git',
remoteBranch: 'branchname',
});
expect(parseRemoteValue('https://some.gitlab.domain/some/path/username/repo/-/tree/branchname')).toEqual({
repoUrl: 'https://some.gitlab.domain/some/path/username/repo.git',
remoteBranch: 'branchname',
});
});

test('should get correct commit hash from url', () => {
expect(
parseRemoteValue(
'https://some.gitlab.domain/some/path/username/repo/commit/c482755296cce46e58f87d50f25f545c5d15be6f',
),
).toEqual({
repoUrl: 'https://some.gitlab.domain/some/path/username/repo.git',
remoteBranch: 'c482755296cce46e58f87d50f25f545c5d15be6f',
});
});
test('should throw when the URL is invalid or harmful', () => {
expect(() => parseRemoteValue('some random string')).toThrowError();
});
});

Expand Down

0 comments on commit c75ea41

Please sign in to comment.