web-dev-qa-db-ja.com

angular回路図でファイルを上書きする方法は?

毎回ファイルを上書きするRuleを書きたいのですが。以下では、MergeStrategyOverwriteに設定します。

collection.json

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "function": {
      "aliases": [ "fn" ],
      "factory": "./function",
      "description": "Create a function.",
      "schema": "./function/schema.json"
    }
  }
}

function/index.ts

export default function(options: FunctionOptions): Rule {
  options.path = options.path ? normalize(options.path) : options.path;
  const sourceDir = options.sourceDir;
  if (!sourceDir) {
    throw new SchematicsException(`sourceDir option is required.`);
  }

  const templateSource: Source = apply(
    url('./files'),
    [
      template({
        ...strings,
        ...options,
      }),
      move(sourceDir),
    ]
  )

  return mergeWith(templateSource, MergeStrategy.Overwrite);

}

files/__path__/__name@dasherize__.ts

export function <%= camelize(name) %>(): void {
}

走る schematics .:function --name=test --dry-run=falseなる

CREATE /src/app/test.ts(33バイト)

しかし、その後、2回目。

エラー! /src/app/test.tsはすでに存在します。

エラーなしでファイルtest.tsを上書きしないでください。

編集:

すべての回答が機能し、すばらしいですが、回避策であり、明らかな「正しい」回答ではなく、おそらく好み/意見に基づいているようです。したがって、回答済みとしてマークする方法がわかりません。

14
William Lohan

同じ問題が発生しました。誤って、forEachapplyに追加すると、ファイルを削除して新しいファイルを作成できることがわかりました。これは@ angular-devkit/schematics-cli @ 0.6.8で使用できます。

export function indexPage(options: any): Rule {
    return (tree: Tree, _context: SchematicContext) => {
        const rule = mergeWith(
            apply(url('./files'), [
                template({ ...options }),
                forEach((fileEntry: FileEntry) => {
                    // Just by adding this is allows the file to be overwritten if it already exists
                    if (tree.exists(fileEntry.path)) return null;
                    return fileEntry;
                })

            ])
        );

        return rule(tree, _context);
    };
}
6
chris

クリスの答えを変更する私は次の解決策を思い付くことができました:

export function applyWithOverwrite(source: Source, rules: Rule[]): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    const rule = mergeWith(
      apply(source, [
        ...rules,
        forEach((fileEntry) => {
          if (tree.exists(fileEntry.path)) {
            tree.overwrite(fileEntry.path, fileEntry.content);
            return null;
          }
          return fileEntry;
        }),

      ]),
    );

    return rule(tree, _context);
  };
}

applyの使用をこの関数の呼び出しに置き換えます。

 applyWithOverwrite(url('./files/stylelint'), [
        template({
          dot: '.',
        }),
      ]),
8
cgatian

多くのファイルを置き換える場合、これは理想的ではありません。プロジェクトにボイラープレートを追加しているときに、favicon.icoを置き換えるこの問題に遭遇しました。私が使用する解決策は、最初に明示的に削除することです。

export function scaffold(options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
  
    tree.delete('src/favicon.ico');

    const templateSource = apply(url('./files'), [
      template({
        ...options,
      }),
      move('.'),
    ]);

    return chain([
      branchAndMerge(chain([
        mergeWith(templateSource, MergeStrategy.Overwrite),
      ]), MergeStrategy.AllowOverwriteConflict),
    ])(tree, _context);
  };
}

注:このアプローチは、現在のバージョンのSchematicsでは機能しません。

以下は、0.6.8の回路図で機能するようです。

export function scaffold(options: any): Rule {
  return (tree: Tree, _context: SchematicContext) => {
  
    const templateSource = apply(url('./files'), [
      template({
        ...options,
      }),
      move('.'),
    ]);

    return chain([
      branchAndMerge(chain([
        mergeWith(templateSource, MergeStrategy.Overwrite),
      ]), MergeStrategy.Overwrite),
    ])(tree, _context);
  };
}

おまけとして、ファイルを明示的に削除する必要がなくなりました。

3
Martin

そのヒントをありがとう@cgatian!
残念ながら、テンプレートをある場所にmove動作しなかったため、以下を追加する必要がありました。

forEach(fileEntry => {
  const destPath = join(options.output, fileEntry.path);
  if (tree.exists(destPath)) {
    tree.overwrite(destPath, fileEntry.content);
  } else {
    tree.create(destPath, fileEntry.content);
  }
  return null;
})

MergeStrategyが期待どおりに機能するまで、
これはoptions.outputで宛先パスを渡すトリックを実行します!

再度、感謝します!

0
Mateo Tibaquira