Je veux écrire une Rule
qui écrase un fichier à chaque fois. Dans ce qui suit, MergeStrategy
est défini sur 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 {
}
Je lance schematics .:function --name=test --dry-run=false
je reçois
CREATE /src/app/test.ts (33 octets)
mais alors, la deuxième fois.
ERREUR! /src/app/test.ts existe déjà.
Ne devrait-il pas écraser le fichier test.ts sans erreur?
Modifier:
Toutes les réponses fonctionnent et sont excellentes, mais il semble que ce soient des solutions de contournement et aucune réponse "juste" évidente et éventuellement basées sur des préférences/opinions Donc, pas sûr de savoir comment marquer comme répondu.
J'ai vécu le même problème. Par accident, j'ai constaté que l'ajout d'une forEach
à la apply
permettait la suppression des fichiers et la création de nouveaux fichiers. Ceci est avec @ 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);
};
}
Cela peut ne pas être idéal si vous remplacez plusieurs fichiers. Je suis tombé sur ce problème en remplaçant le favicon.ico tout en ajoutant un passe-partout au projet. La solution que j'utilise est de le supprimer explicitement en premier.
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);
};
}
REMARQUE: cette approche ne fonctionne plus avec les versions actuelles de Schematics.
Ce qui suit semble fonctionner pour les schémas 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);
};
}
En prime, je n'ai plus besoin de supprimer explicitement le fichier.
En modifiant la réponse de chris, j'ai pu proposer la solution suivante:
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);
};
}
Remplacez votre utilisation de apply
par des appels à cette fonction.
applyWithOverwrite(url('./files/stylelint'), [
template({
dot: '.',
}),
]),
Merci @ cgatian pour cet indice!
Malheureusement, cela n'a pas fonctionné pour move
les modèles à un endroit donné, j'ai donc dû ajouter:
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;
})
Jusqu'à ce que MergeStrategy
fonctionne comme prévu,
cela fera l’astuce en passant le chemin de destination dans options.output
!
Merci encore!