0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

Improves display of preferences list command (#9292)

Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
Nate Moore 2023-12-04 13:56:37 -06:00 committed by GitHub
parent fd9ffe2062
commit 5428b3da08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 20 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Improves display for `astro preferences list` command

View file

@ -2,7 +2,7 @@
import type yargs from 'yargs-parser'; import type yargs from 'yargs-parser';
import type { AstroSettings } from '../../@types/astro.js'; import type { AstroSettings } from '../../@types/astro.js';
import { bold } from 'kleur/colors'; import { bgGreen, black, bold, dim } from 'kleur/colors';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import dlv from 'dlv'; import dlv from 'dlv';
@ -10,7 +10,7 @@ import { resolveConfig } from '../../core/config/config.js';
import { createSettings } from '../../core/config/settings.js'; import { createSettings } from '../../core/config/settings.js';
import * as msg from '../../core/messages.js'; import * as msg from '../../core/messages.js';
import { DEFAULT_PREFERENCES } from '../../preferences/defaults.js'; import { DEFAULT_PREFERENCES } from '../../preferences/defaults.js';
import { coerce, isValidKey, type PreferenceKey } from '../../preferences/index.js'; import { coerce, isValidKey, type PreferenceKey, type PreferenceLocation } from '../../preferences/index.js';
import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js'; import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js';
// @ts-expect-error flattie types are mispackaged // @ts-expect-error flattie types are mispackaged
import { flattie } from 'flattie'; import { flattie } from 'flattie';
@ -211,12 +211,52 @@ async function resetPreference(
} }
async function listPreferences(settings: AstroSettings, { location, json }: SubcommandOptions) { async function listPreferences(settings: AstroSettings, { location, json }: SubcommandOptions) {
const store = await settings.preferences.getAll({ location });
if (json) { if (json) {
console.log(JSON.stringify(store, null, 2)); const resolved = await settings.preferences.getAll();
console.log(JSON.stringify(resolved, null, 2));
return 0; return 0;
} }
prettyPrint(store); const { global, project, defaults } = await settings.preferences.list({ location });
const flatProject = flattie(project);
const flatGlobal = flattie(global);
const flatUser = Object.assign({}, flatGlobal, flatProject);
for (let key of Object.keys(flatUser)) {
if (!isValidKey(key)) {
delete flatUser[key];
continue;
}
}
const flatDefault = flattie(defaults);
const userKeys = Object.keys(flatUser);
if (userKeys.length > 0) {
const badge = bgGreen(black(` Your Preferences `));
const table = formatTable(flatUser, ['Preference', 'Value']);
console.log(['', badge, table].join('\n'));
} else {
const badge = bgGreen(black(` Your Preferences `));
const message = dim('No preferences set');
console.log(['', badge, '', message].join('\n'));
}
const flatUnset = Object.assign({}, flatDefault);
for (const key of userKeys) {
delete flatUnset[key];
}
const unsetKeys = Object.keys(flatUnset);
if (unsetKeys.length > 0) {
const badge = bgGreen(black(` Default Preferences `));
const table = formatTable(flatUnset, ['Preference', 'Value']);
console.log(['', badge, table].join('\n'));
} else {
const badge = bgGreen(black(` Default Preferences `));
const message = dim('All preferences have been set');
console.log(['', badge, '', message].join('\n'));
}
return 0; return 0;
} }
@ -256,19 +296,19 @@ function formatTable(
b: string | number | boolean, b: string | number | boolean,
style: (value: string | number | boolean) => string = (v) => v.toString() style: (value: string | number | boolean) => string = (v) => v.toString()
): string { ): string {
return `${chars.v} ${style(a)} ${space(colALength - a.length - 2)} ${chars.v} ${style( return `${dim(chars.v)} ${style(a)} ${space(colALength - a.length - 2)} ${dim(chars.v)} ${style(
b b
)} ${space(colBLength - b.toString().length - 3)} ${chars.v}`; )} ${space(colBLength - b.toString().length - 3)} ${dim(chars.v)}`;
} }
const top = `${chars.topLeft}${chars.h.repeat(colALength + 1)}${chars.hBottom}${chars.h.repeat( const top = dim(`${chars.topLeft}${chars.h.repeat(colALength + 1)}${chars.hBottom}${chars.h.repeat(
colBLength colBLength
)}${chars.topRight}`; )}${chars.topRight}`);
const bottom = `${chars.bottomLeft}${chars.h.repeat(colALength + 1)}${chars.hTop}${chars.h.repeat( const bottom = dim(`${chars.bottomLeft}${chars.h.repeat(colALength + 1)}${chars.hTop}${chars.h.repeat(
colBLength colBLength
)}${chars.bottomRight}`; )}${chars.bottomRight}`);
const divider = `${chars.vRightThick}${chars.hThick.repeat(colALength + 1)}${ const divider = dim(`${chars.vRightThick}${chars.hThick.repeat(colALength + 1)}${
chars.hThickCross chars.hThickCross
}${chars.hThick.repeat(colBLength)}${chars.vLeftThick}`; }${chars.hThick.repeat(colBLength)}${chars.vLeftThick}`);
const rows: string[] = [top, formatRow(-1, colA, colB, bold), divider]; const rows: string[] = [top, formatRow(-1, colA, colB, bold), divider];
let i = 0; let i = 0;
for (const [key, value] of Object.entries(object)) { for (const [key, value] of Object.entries(object)) {

View file

@ -22,11 +22,19 @@ export type GetDotKey<
K extends string, K extends string,
> = K extends `${infer U}.${infer Rest}` ? GetDotKey<T[U], Rest> : T[K]; > = K extends `${infer U}.${infer Rest}` ? GetDotKey<T[U], Rest> : T[K];
export type PreferenceLocation = 'global' | 'project';
export interface PreferenceOptions { export interface PreferenceOptions {
location?: 'global' | 'project'; location?: PreferenceLocation;
} }
type DeepPartial<T> = T extends object ? {
[P in keyof T]?: DeepPartial<T[P]>;
} : T;
export type PreferenceKey = DotKeys<Preferences>; export type PreferenceKey = DotKeys<Preferences>;
export interface PreferenceList extends Record<PreferenceLocation, DeepPartial<Preferences>> {
defaults: Preferences;
}
export interface AstroPreferences { export interface AstroPreferences {
get<Key extends PreferenceKey>( get<Key extends PreferenceKey>(
@ -38,7 +46,8 @@ export interface AstroPreferences {
value: GetDotKey<Preferences, Key>, value: GetDotKey<Preferences, Key>,
opts?: PreferenceOptions opts?: PreferenceOptions
): Promise<void>; ): Promise<void>;
getAll(opts?: PreferenceOptions): Promise<Record<string, any>>; getAll(): Promise<Preferences>;
list(opts?: PreferenceOptions): Promise<PreferenceList>;
} }
export function isValidKey(key: string): key is PreferenceKey { export function isValidKey(key: string): key is PreferenceKey {
@ -62,7 +71,7 @@ export function coerce(key: string, value: unknown) {
export default function createPreferences(config: AstroConfig): AstroPreferences { export default function createPreferences(config: AstroConfig): AstroPreferences {
const global = new PreferenceStore(getGlobalPreferenceDir()); const global = new PreferenceStore(getGlobalPreferenceDir());
const project = new PreferenceStore(fileURLToPath(new URL('./.astro/', config.root))); const project = new PreferenceStore(fileURLToPath(new URL('./.astro/', config.root)));
const stores = { global, project }; const stores: Record<PreferenceLocation, PreferenceStore> = { global, project };
return { return {
async get(key, { location } = {}) { async get(key, { location } = {}) {
@ -72,10 +81,15 @@ export default function createPreferences(config: AstroConfig): AstroPreferences
async set(key, value, { location = 'project' } = {}) { async set(key, value, { location = 'project' } = {}) {
stores[location].set(key, value); stores[location].set(key, value);
}, },
async getAll({ location } = {}) { async getAll() {
if (!location) return Object.assign({}, DEFAULT_PREFERENCES, stores['global'].getAll(), stores['project'].getAll());
return Object.assign({}, stores['global'].getAll(), stores['project'].getAll()); },
return stores[location].getAll(); async list() {
return {
global: stores['global'].getAll(),
project: stores['project'].getAll(),
defaults: DEFAULT_PREFERENCES,
};
}, },
}; };
} }