Skip to content

Commit adcaf87

Browse files
committed
feat(schematics): enhance logging UX with colored changeset summary
- Refactor ng-add and sync logs to use a unified Changeset aesthetic\n- Add ANSI colors to status symbols (A, M, ✔, ℹ)\n- Silence individual process logs for a cleaner terminal output\n- Clean up unused code and fix lint errors
1 parent db29699 commit adcaf87

4 files changed

Lines changed: 115 additions & 167 deletions

File tree

projects/ngx-theme-stack/schematics/ng-add/anti-flash.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,8 @@ export function patchIndexHtml(
9090
const SCRIPT_BLOCK_RE = /<!--\s*ngx-theme-stack\s*anti-flash\s*-->\s*<script[^>]*>[\s\S]*?<\/script>/;
9191
if (SCRIPT_BLOCK_RE.test(updated)) {
9292
updated = updated.replace(SCRIPT_BLOCK_RE, scriptTag);
93-
context.logger.info(`✔ Updated anti-flash script in ${path}`);
9493
} else {
9594
updated = updated.replace('<head>', `<head>${scriptTag}`);
96-
context.logger.info(`✔ Injected anti-flash script into ${path}`);
9795
}
9896

9997
// ── 2. Update Critters Trick ─────────────────────────────────────────────
@@ -118,13 +116,10 @@ export function patchIndexHtml(
118116

119117
if (CRITTERS_BLOCK_RE.test(updated)) {
120118
updated = updated.replace(CRITTERS_BLOCK_RE, crittersBlock);
121-
context.logger.info(`✔ Updated Critters-trick block in ${path}`);
122119
} else if (CRITTERS_ID_RE.test(updated)) {
123120
updated = updated.replace(CRITTERS_ID_RE, crittersBlock);
124-
context.logger.info(`✔ Wrapped existing Critters-trick div with markers in ${path}`);
125121
} else {
126122
updated = updated.replace('</body>', ` ${crittersBlock}\n </body>`);
127-
context.logger.info(`✔ Injected Critters-trick block before </body> in ${path}`);
128123
}
129124
} else {
130125
// If switching to blocking strategy, remove existing trick
@@ -133,7 +128,6 @@ export function patchIndexHtml(
133128
} else if (CRITTERS_ID_RE.test(updated)) {
134129
updated = updated.replace(CRITTERS_ID_RE, '');
135130
}
136-
context.logger.info(`✔ Removed Critters-trick from ${path}`);
137131
}
138132

139133
tree.overwrite(path, updated);

projects/ngx-theme-stack/schematics/ng-add/app-config.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export function patchAppConfig(
2727
if (updated.includes('provideThemeStack')) {
2828
updated = updated.replace(/provideThemeStack\s*\([\s\S]*?\)/, provideCall);
2929
tree.overwrite(filePath, updated);
30-
context.logger.info(`✔ Updated provideThemeStack configuration in ${filePath}`);
3130
return;
3231
}
3332

@@ -59,7 +58,6 @@ export function patchAppConfig(
5958
}
6059

6160
tree.overwrite(filePath, updated);
62-
context.logger.info(`✔ Added ${provideCall} to ${filePath}`);
6361
return;
6462
}
6563

projects/ngx-theme-stack/schematics/ng-add/index.ts

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export function ngAdd(options: Schema): Rule {
9292
let finalThemes: string[];
9393
let themesToScaffold: string[];
9494
let finalStrategy: 'critters' | 'blocking';
95+
const changeset: string[] = [];
9596

9697
if (options.mode === 'quick') {
9798
const themes = [...DEFAULT_THEMES];
@@ -108,13 +109,6 @@ export function ngAdd(options: Schema): Rule {
108109
const opts = await collectCustomOptions();
109110
const { defaultTheme, storageKey, mode, themes, strategy } = opts;
110111

111-
context.logger.info(' Applying your configuration:');
112-
context.logger.info(` defaultTheme : ${defaultTheme}`);
113-
context.logger.info(` themes : [${themes.join(', ')}]`);
114-
context.logger.info(` storageKey : ${storageKey}`);
115-
context.logger.info(` mode : ${mode}`);
116-
context.logger.info(` strategy : ${strategy}`);
117-
118112
provideCall = buildProvideCall(defaultTheme, storageKey, mode, themes, strategy);
119113
scriptOptions = { storageKey, defaultTheme, mode };
120114
finalThemes = themes;
@@ -123,7 +117,7 @@ export function ngAdd(options: Schema): Rule {
123117
}
124118

125119
return chain([
126-
(t: Tree, context: SchematicContext) => {
120+
(t: Tree) => {
127121
const themesPath = `${projectSourceRoot}/themes.css`;
128122
if (!t.exists(themesPath)) {
129123
let content = '/* ngx-theme-stack tokens */\n\n';
@@ -140,16 +134,9 @@ export function ngAdd(options: Schema): Rule {
140134
});
141135

142136
t.create(themesPath, content);
143-
context.logger.info(`\n \u001b[36mResume :\u001b[0m \n`);
144-
context.logger.info(`\u001b[32m✔ Created ${themesPath} with your theme selectors.\u001b[0m`);
137+
changeset.push(` \u001b[36mA\u001b[0m ${themesPath.replace(/^\//, '')} (theme tokens)`);
145138
} else {
146-
context.logger.info(`\n \u001b[36mResume :\u001b[0m \n`);
147-
context.logger.info(
148-
`\u001b[33mℹ ${themesPath} already exists. Skipping creation to preserve your styles.\u001b[0m`,
149-
);
150-
context.logger.info(
151-
` Tip: Make sure to manually add selectors (class or attribute) for any new themes.`,
152-
);
139+
changeset.push(` \u001b[90mℹ\u001b[0m ${themesPath.replace(/^\//, '')} (already exists)`);
153140
}
154141
},
155142
(t: Tree) => {
@@ -160,9 +147,10 @@ export function ngAdd(options: Schema): Rule {
160147
pkg.scripts = pkg.scripts || {};
161148
pkg.scripts.prebuild = `ng generate ngx-theme-stack:sync --project ${projectName}`;
162149
t.overwrite(pkgPath, JSON.stringify(pkg, null, 2));
150+
changeset.push(' \u001b[33mM\u001b[0m package.json (prebuild script)');
163151
}
164152
},
165-
(t: Tree, context: SchematicContext) => {
153+
(t: Tree) => {
166154
const workspaceConfig = t.read('/angular.json');
167155
if (workspaceConfig) {
168156
const workspace = JSON.parse(workspaceConfig.toString());
@@ -186,21 +174,27 @@ export function ngAdd(options: Schema): Rule {
186174
styles: { inlineCritical: false },
187175
};
188176
}
189-
context.logger.info(`✔ Disabled inlineCritical in angular.json for blocking strategy.`);
190177
}
191178

192179
t.overwrite('/angular.json', JSON.stringify(workspace, null, 2));
180+
changeset.push(' \u001b[33mM\u001b[0m angular.json (styles & optimization)');
193181
}
194182
},
195183
(t: Tree, ctx: SchematicContext) => {
196184
patchAppConfig(t, ctx, projectSourceRoot, provideCall);
185+
changeset.push(' \u001b[33mM\u001b[0m app.config.ts (provided theme stack)');
186+
197187
patchIndexHtml(t, ctx, projectSourceRoot, {
198188
...scriptOptions,
199189
themes: finalThemes,
200190
strategy: (options.strategy as 'critters' | 'blocking') || finalStrategy,
201191
});
192+
changeset.push(' \u001b[33mM\u001b[0m index.html (injected anti-flash)');
193+
194+
ctx.logger.info('\u001b[1mChangeset:\u001b[0m');
195+
changeset.forEach((entry) => ctx.logger.info(entry));
202196
ctx.logger.info('');
203-
ctx.logger.info('Done! ngx-theme-stack is ready with automatic sync on build.');
197+
ctx.logger.info('\u001b[1m\u001b[32m🏁 Done.\u001b[0m');
204198
ctx.logger.info('');
205199
},
206200
]);

0 commit comments

Comments
 (0)