|
import chalk from 'npm:chalk'; |
|
|
|
export const getHostFromRepo = (repo: string): string => { |
|
let host: string; |
|
|
|
if (repo.startsWith('git@')) { |
|
const repoParts = repo.split(':'); |
|
host = repoParts[0].split('@')[1].split('.')[0]; |
|
} else if (repo.startsWith('https://')) { |
|
const repoParts = repo.split('/'); |
|
host = repoParts[2].split('.')[0]; |
|
} else { |
|
console.error(chalk.bgRedBright(`Invalid Git repository URL: ${repo}`)); |
|
Deno.exit(1); |
|
} |
|
|
|
return host; |
|
}; |
|
|
|
export const getDirPathFromRepo = (repo: string): string => { |
|
let dirPath: string; |
|
|
|
if (repo.startsWith('git@')) { |
|
const repoParts = repo.split(':'); |
|
dirPath = repoParts[1].replace('.git', ''); |
|
} else if (repo.startsWith('https://')) { |
|
const repoParts = repo.split('/'); |
|
dirPath = repoParts.slice(3).join('/').replace('.git', ''); |
|
} else { |
|
console.error(chalk.bgRedBright(`Invalid Git repository URL: ${repo}`)); |
|
Deno.exit(1); |
|
} |
|
|
|
return dirPath; |
|
}; |
|
|
|
export const getLocalPath = (repo: string, targetBaseDir: string): string => { |
|
const host = getHostFromRepo(repo); |
|
const dirPath = getDirPathFromRepo(repo); |
|
const targetPath = `${targetBaseDir}/${host}/${dirPath}`; |
|
|
|
// find all sequential directories that exist |
|
const dirs = targetPath.split('/'); |
|
const remainingPath: string[] = []; |
|
|
|
for (const dir of dirs) { |
|
if (!remainingPath.includes(dir)) { |
|
remainingPath.push(dir); |
|
} |
|
} |
|
|
|
return remainingPath.join('/'); |
|
}; |
|
|
|
interface ShortenOptions { |
|
separator?: string; |
|
min?: number; |
|
left?: number; |
|
right?: number; |
|
} |
|
|
|
export const shortenPath = (path: string, options?: ShortenOptions): string => { |
|
const min = options?.min ?? 3; |
|
const separator = options?.separator ?? '/'; |
|
const parts = path.split(separator); |
|
|
|
if (parts.length <= min) { |
|
return path; |
|
} |
|
|
|
const left = options?.left ?? 1; |
|
const first = parts.slice(0, left + 1).join('/'); |
|
|
|
const right = options?.right ?? 2; |
|
const last = parts.slice(-right).join('/'); |
|
|
|
return `${first}/.../${last}`; |
|
}; |
|
|
|
export const findExecutablePath = async ( |
|
executable: string |
|
): Promise<string> => { |
|
try { |
|
const command = await new Deno.Command('which', { |
|
args: [executable], |
|
stdout: 'piped', |
|
}); |
|
const { stdout } = await command.output(); |
|
|
|
return new TextDecoder().decode(stdout).trim(); |
|
} catch (error) { |
|
console.error(chalk.bgRedBright(`Error finding git path: ${error}`)); |
|
Deno.exit(1); |
|
} |
|
}; |
|
|
|
export const runExecutable = async ( |
|
executable: string, |
|
args: string[] |
|
): Promise<Deno.CommandStatus> => { |
|
const command = await new Deno.Command(executable, { |
|
args, |
|
stdin: 'piped', |
|
}); |
|
const child = await command.spawn(); |
|
const status = await child.status; |
|
|
|
return status; |
|
}; |
|
|
|
export const fetchRepo = async (localRepo: string): Promise<void> => { |
|
const git = await findExecutablePath('git'); |
|
|
|
const pull = new Deno.Command(git, { |
|
cwd: localRepo, |
|
args: ['fetch', 'origin'], |
|
stdin: 'piped', |
|
}); |
|
const child = await pull.spawn(); |
|
const status = await child.status; |
|
|
|
if (!status.success) { |
|
console.error(chalk.bgRedBright(`Error fetching repository`)); |
|
} else { |
|
console.log(chalk.bgGreenBright(`Repository fetching successfully`)); |
|
} |
|
}; |
|
|
|
export const cloneRepo = async ( |
|
repo: string, |
|
localRepo: string |
|
): Promise<void> => { |
|
const git = await findExecutablePath('git'); |
|
|
|
const clone = new Deno.Command(git, { |
|
args: ['clone', repo, localRepo], |
|
stdin: 'piped', |
|
}); |
|
const child = await clone.spawn(); |
|
const status = await child.status; |
|
|
|
if (!status.success) { |
|
console.error(chalk.bgRedBright(`Error cloning repository`)); |
|
} else { |
|
console.log( |
|
chalk.bgGreenBright(`Repository cloned successfully to ${localRepo}`) |
|
); |
|
} |
|
}; |