Skip to content

Commit

Permalink
create-extension cli: handle deleted files (#163)
Browse files Browse the repository at this point in the history
Co-authored-by: Shiv Bhonde <[email protected]>
  • Loading branch information
moltam89 and technophile-04 authored Dec 7, 2024
1 parent ef55492 commit 16e6a9e
Showing 1 changed file with 62 additions and 8 deletions.
70 changes: 62 additions & 8 deletions src/dev/create-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,32 @@ const getProjectPath = (rawArgs: string[]) => {
return { projectPath };
};

const getChangedFilesFromFirstCommit = async (projectPath: string): Promise<string[]> => {
const getDeletedFiles = async (projectPath: string): Promise<string[]> => {
const { stdout: allFiles } = await execa(
"git",
["log", "--all", "--diff-filter=ACDMRT", "--name-only", "--format="],
{ cwd: projectPath },
);

const { stdout: currentFiles } = await execa("git", ["ls-files"], {
cwd: projectPath,
});

const allFilesSet = new Set(allFiles.split("\n").filter(Boolean));
const currentFilesArray = currentFiles.split("\n").filter(Boolean);

return Array.from(allFilesSet).filter(file => !currentFilesArray.includes(file));
};

const getChangedFilesSinceFirstCommit = async (projectPath: string): Promise<string[]> => {
const { stdout: firstCommit } = await execa("git", ["rev-list", "--max-parents=0", "HEAD"], {
cwd: projectPath,
});
const { stdout } = await execa("git", ["diff", "--name-only", `${firstCommit.trim()}..HEAD`], {

const { stdout } = await execa("git", ["diff", "--diff-filter=d", "--name-only", `${firstCommit.trim()}..HEAD`], {
cwd: projectPath,
});

return stdout.split("\n").filter(Boolean);
};

Expand Down Expand Up @@ -77,13 +96,47 @@ const findTemplateFiles = async (dir: string, templates: Set<string>) => {
}
};

const copyFiles = async (files: string[], projectName: string, projectPath: string, templates: Set<string>) => {
for (const file of files) {
const copyChanges = async (
changedFiles: string[],
deletedFiles: string[],
projectName: string,
projectPath: string,
templates: Set<string>,
) => {
for (const file of deletedFiles) {
const destPath = path.join(EXTERNAL_EXTENSIONS_DIR, projectName, TARGET_EXTENSION_DIR, file);
if (fs.existsSync(destPath)) {
await fs.promises.unlink(destPath);
prettyLog.success(`Removed deleted file: ${file}`, 2);
console.log("\n");

// remove empty directories
const dirPath = path.dirname(destPath);
try {
const remainingFiles = await fs.promises.readdir(dirPath);
if (remainingFiles.length === 0) {
await fs.promises.rmdir(dirPath);
prettyLog.success(`Removed empty directory: ${path.relative(EXTERNAL_EXTENSIONS_DIR, dirPath)}`, 2);
console.log("\n");
}
} catch {
// directory might already be deleted, ignore error
}
}
}

for (const file of changedFiles) {
const pathSegmentsOfFile = file.split(path.sep);
const sourcePath = path.resolve(projectPath, file);
const destPath = path.join(EXTERNAL_EXTENSIONS_DIR, projectName, TARGET_EXTENSION_DIR, file);
const sourceFileName = path.basename(sourcePath);

if (!fs.existsSync(sourcePath)) {
prettyLog.warning(`Source file not found, skipping: ${file}`, 2);
console.log("\n");
continue;
}

if (templates.has(file)) {
prettyLog.warning(`Skipping file: ${file}`, 2);
prettyLog.info(`Please instead create/update: ${destPath}.args.mjs`, 3);
Expand Down Expand Up @@ -150,15 +203,16 @@ const main = async (rawArgs: string[]) => {
prettyLog.info(`Extension name: ${projectName}\n`);

prettyLog.info("Getting list of changed files...", 1);
const changedFiles = await getChangedFilesFromFirstCommit(projectPath);
const changedFiles = await getChangedFilesSinceFirstCommit(projectPath);
const deletedFiles = await getDeletedFiles(projectPath);

if (changedFiles.length === 0) {
prettyLog.warning("No changed files to copy.", 1);
if (changedFiles.length === 0 && deletedFiles.length === 0) {
prettyLog.warning("There are no file changes to copy.", 1);
console.log("\n");
} else {
prettyLog.info(`Found ${changedFiles.length} changed files, processing them...`, 1);
console.log("\n");
await copyFiles(changedFiles, projectName, projectPath, templates);
await copyChanges(changedFiles, deletedFiles, projectName, projectPath, templates);
}

prettyLog.info(`Files processed successfully, updated ${EXTERNAL_EXTENSIONS_DIR}/${projectName} directory.`);
Expand Down

0 comments on commit 16e6a9e

Please sign in to comment.