毎回ファイルを上書きするRule
を書きたいのですが。以下では、MergeStrategy
をOverwrite
に設定します。
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を上書きしないでください。
編集:
すべての回答が機能し、すばらしいですが、回避策であり、明らかな「正しい」回答ではなく、おそらく好み/意見に基づいているようです。したがって、回答済みとしてマークする方法がわかりません。
同じ問題が発生しました。誤って、forEach
をapply
に追加すると、ファイルを削除して新しいファイルを作成できることがわかりました。これは@ 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);
};
}
クリスの答えを変更する私は次の解決策を思い付くことができました:
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: '.',
}),
]),
多くのファイルを置き換える場合、これは理想的ではありません。プロジェクトにボイラープレートを追加しているときに、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);
};
}
おまけとして、ファイルを明示的に削除する必要がなくなりました。
そのヒントをありがとう@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
で宛先パスを渡すトリックを実行します!
再度、感謝します!