10000 fix(@schematics/angular): make ai-config schematic non-destructive · angular/angular-cli@e304821 · GitHub
[go: up one dir, main page]

Skip to content
  • Pricing
  • Search code, repositories, users, issues, pull requests...

    Provide feedback

    We read every piece of feedback, and take your input very seriously.

    Saved searches

    Use saved searches to filter your results more quickly

    Appearance settings

    Commit e304821

    Browse files
    committed
    fix(@schematics/angular): make ai-config schematic non-destructive
    The ai-config schematic will now check if a configuration file already exists before generating a new one. If a file is present, the schematic will skip it and log a detailed, actionable warning to the console. This change prevents the accidental overwriting of user-customized configuration files, making the schematic safer to run multiple times. The warning message informs the user why the file was skipped and instructs them on how to regenerate it if they wish to revert to the default settings. A unit test is included to verify this non-destructive behavior.
    1 parent 7c1ef7f commit e304821

    File tree

    2 files changed

    +57
    -19
    lines changed

    2 files changed

    +57
    -19
    lines changed

    packages/schematics/angular/ai-config/index.ts

    Lines changed: 35 additions & 19 deletions
    Original file line numberDiff line numberDiff line change
    @@ -55,25 +55,41 @@ interface ContextFileInfo {
    5555
    }
    5656

    5757
    export default function ({ tool }: ConfigOptions): Rule {
    58-
    if (!tool) {
    59-
    return noop();
    60-
    }
    58+
    return (tree, context) => {
    59+
    if (!tool) {
    60+
    return noop();
    61+
    }
    6162

    62-
    const rules = tool
    63-
    .filter((tool) => tool !== Tool.None)
    64-
    .map((selectedTool) => AI_TOOLS[selectedTool])
    65-
    .map(({ rulesName, directory, frontmatter }) =>
    66-
    mergeWith(
    67-
    apply(url('./files'), [
    68-
    applyTemplates({
    69-
    ...strings,
    70-
    rulesName,
    71-
    frontmatter,
    72-
    }),
    73-
    move(directory),
    74-
    ]),
    75-
    ),
    76-
    );
    63+
    const rules = tool
    64+
    .filter((tool) => tool !== Tool.None)
    65+
    .map((selectedTool) => {
    66+
    const { rulesName, directory, frontmatter } = AI_TOOLS[selectedTool];
    67+
    const path = `${directory}/${rulesName}`;
    7768

    78-
    return chain(rules);
    69+
    if (tree.exists(path)) {
    70+
    const toolName = strings.classify(selectedTool);
    71+
    context.logger.warn(
    72+
    `Skipping configuration file for '${toolName}' at '${path}' because it already exists.\n` +
    73+
    'This is to prevent overwriting a potentially customized file. ' +
    74+
    'If you want to regenerate it with Angular recommended defaults, please delete the existing file and re-run the command.\n' +
    75+
    'You can review the latest recommendations at https://angular.dev/ai/develop-with-ai.',
    76+
    );
    77+
    78+
    return noop();
    79+
    }
    80+
    81+
    return mergeWith(
    82+
    apply(url('./files'), [
    83+
    applyTemplates({
    84+
    ...strings,
    85+
    rulesName,
    86+
    frontmatter,
    87+
    }),
    88+
    move(directory),
    89+
    ]),
    90+
    );
    91+
    });
    92+
    93+
    return chain(rules);
    94+
    };
    7995
    }

    packages/schematics/angular/ai-config/index_spec.ts

    Lines changed: 22 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -78,6 +78,28 @@ describe('Ai Config Schematic', () => {
    7878
    expect(tree.files.length).toBe(filesCount);
    7979
    });
    8080

    81+
    it('should not overwrite an existing file', async () => {
    82+
    const customContent = 'custom user content';
    83+
    workspaceTree.create('.gemini/GEMINI.md', customContent);
    84+
    85+
    const messages: string[] = [];
    86+
    const loggerSubscription = schematicRunner.logger.subscribe((x) => messages.push(x.message));
    87+
    88+
    try {
    89+
    const tree = await runConfigSchematic([ConfigTool.Gemini]);
    90+
    91+
    expect(tree.readContent('.gemini/GEMINI.md')).toBe(customContent);
    92+
    expect(messages).toContain(
    93+
    `Skipping configuration file for 'Gemini' at '.gemini/GEMINI.md' because it already exists.\n` +
    94+
    'This is to prevent overwriting a potentially customized file. ' +
    95+
    'If you want to regenerate it with Angular recommended defaults, please delete the existing file and re-run the command.\n' +
    96+
    'You can review the latest recommendations at https://angular.dev/ai/develop-with-ai.',
    97+
    );
    98+
    } finally {
    99+
    loggerSubscription.unsubscribe();
    100+
    }
    101+
    });
    102+
    81103
    it('should create for tool if None and Gemini are selected', async () => {
    82104
    const tree = await runConfigSchematic([ConfigTool.Gemini, ConfigTool.None]);
    83105
    expect(tree.exists('.gemini/GEMINI.md')).toBeTruthy();

    0 commit comments

    Comments
     (0)
    0