feat(sync): select label color from flag or state, value, and project
This commit is contained in:
parent
e4ab01ad10
commit
365a23c85c
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [cautious-journey](./cautious-journey.md) > [SyncOptions](./cautious-journey.syncoptions.md) > [colors](./cautious-journey.syncoptions.colors.md)
|
||||
|
||||
## SyncOptions.colors property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
colors: Array<string>;
|
||||
```
|
|
@ -14,6 +14,7 @@ export interface SyncOptions
|
|||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [colors](./cautious-journey.syncoptions.colors.md) | Array<string> | |
|
||||
| [flags](./cautious-journey.syncoptions.flags.md) | Array<[FlagLabel](./cautious-journey.flaglabel.md)<!-- -->> | |
|
||||
| [logger](./cautious-journey.syncoptions.logger.md) | Logger | |
|
||||
| [project](./cautious-journey.syncoptions.project.md) | string | |
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { doesExist, InvalidArgumentError } from '@apextoaster/js-utils';
|
||||
import { randomItem } from './utils';
|
||||
|
||||
/**
|
||||
* A reference to another label.
|
||||
*/
|
||||
|
@ -113,3 +116,32 @@ export function prioritizeLabels<TLabel extends BaseLabel>(labels: Array<TLabel>
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a label color, preferring the label data if set, falling back to a randomly selected color.
|
||||
*
|
||||
* TODO: this is a terrible overload
|
||||
*/
|
||||
export function colorizeLabel(flag: FlagLabel, colors: Array<string>): string;
|
||||
export function colorizeLabel(state: StateLabel, value: StateValue, colors: Array<string>): string;
|
||||
export function colorizeLabel(label: BaseLabel, colorsOrValue: Array<string> | StateValue, maybeColors?: Array<string>): string {
|
||||
if (Array.isArray(colorsOrValue)) {
|
||||
const { color } = label;
|
||||
if (doesExist(color)) {
|
||||
return color;
|
||||
} else {
|
||||
return randomItem(colorsOrValue);
|
||||
}
|
||||
} else {
|
||||
if (!Array.isArray(maybeColors)) {
|
||||
throw new InvalidArgumentError();
|
||||
}
|
||||
|
||||
const { color = colorsOrValue.color } = label;
|
||||
if (doesExist(color)) {
|
||||
return color;
|
||||
} else {
|
||||
return randomItem(maybeColors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
22
src/main.ts
22
src/main.ts
|
@ -1,4 +1,4 @@
|
|||
import { InvalidArgumentError, isNil, doesExist } from '@apextoaster/js-utils';
|
||||
import { doesExist, InvalidArgumentError, isNil } from '@apextoaster/js-utils';
|
||||
import { createSchema } from '@apextoaster/js-yaml-schema';
|
||||
import { existsSync, readFileSync, realpathSync } from 'fs';
|
||||
import { DEFAULT_SAFE_SCHEMA, safeLoad } from 'js-yaml';
|
||||
|
@ -57,25 +57,29 @@ export async function main(argv: Array<string>): Promise<number> {
|
|||
}, 'startup environment');
|
||||
|
||||
for (const project of config.projects) {
|
||||
if (doesExist(args.project) && !args.project.includes(project.name)) {
|
||||
logger.info({ project: project.name }, 'skipping project');
|
||||
const { colors, flags, name, states } = project;
|
||||
|
||||
if (doesExist(args.project) && !args.project.includes(name)) {
|
||||
logger.info({ project: name }, 'skipping project');
|
||||
continue;
|
||||
}
|
||||
|
||||
const remote = new GithubRemote({
|
||||
...project.remote,
|
||||
dryrun: args.dryrun,
|
||||
data: project.remote.data,
|
||||
dryrun: args.dryrun || project.remote.dryrun,
|
||||
logger,
|
||||
type: project.remote.type,
|
||||
});
|
||||
await remote.connect();
|
||||
|
||||
// mode switch
|
||||
const options: SyncOptions = {
|
||||
flags: project.flags,
|
||||
colors,
|
||||
flags,
|
||||
logger,
|
||||
project: project.name,
|
||||
project: name,
|
||||
remote,
|
||||
states: project.states,
|
||||
states,
|
||||
};
|
||||
switch (mode) {
|
||||
case Commands.ISSUES:
|
||||
|
@ -85,7 +89,7 @@ export async function main(argv: Array<string>): Promise<number> {
|
|||
await syncLabels(options);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentError('unknown mode');
|
||||
throw new InvalidArgumentError('unknown command');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/sync.ts
15
src/sync.ts
|
@ -1,12 +1,13 @@
|
|||
import { doesExist, mustExist } from '@apextoaster/js-utils';
|
||||
import { Logger } from 'noicejs';
|
||||
|
||||
import { FlagLabel, getLabelNames, StateLabel, valueName } from './labels';
|
||||
import { colorizeLabel, FlagLabel, getLabelNames, StateLabel, valueName } from './labels';
|
||||
import { LabelUpdate, Remote } from './remote';
|
||||
import { resolveLabels } from './resolve';
|
||||
import { defaultTo } from './utils';
|
||||
import { defaultTo, defaultUntil } from './utils';
|
||||
|
||||
export interface SyncOptions {
|
||||
colors: Array<string>;
|
||||
flags: Array<FlagLabel>;
|
||||
logger: Logger;
|
||||
project: string;
|
||||
|
@ -88,7 +89,7 @@ export async function createLabel(options: SyncOptions, name: string) {
|
|||
const flag = options.flags.find((it) => name === it.name);
|
||||
if (doesExist(flag)) {
|
||||
await options.remote.createLabel({
|
||||
color: mustExist(flag.color),
|
||||
color: colorizeLabel(flag, options.colors),
|
||||
desc: mustExist(flag.desc),
|
||||
name,
|
||||
project: options.project,
|
||||
|
@ -102,8 +103,8 @@ export async function createLabel(options: SyncOptions, name: string) {
|
|||
const value = state.values.find((it) => valueName(state, it) === name);
|
||||
if (doesExist(value)) {
|
||||
await options.remote.createLabel({
|
||||
color: defaultTo(defaultTo(value.color, state.color), ''),
|
||||
desc: defaultTo(defaultTo(value.desc, state.desc), ''),
|
||||
color: colorizeLabel(state, value, options.colors),
|
||||
desc: defaultUntil(value.desc, state.desc, ''),
|
||||
name: valueName(state, value),
|
||||
project: options.project,
|
||||
});
|
||||
|
@ -138,7 +139,7 @@ export async function syncSingleLabel(options: SyncOptions, label: LabelUpdate):
|
|||
const flag = options.flags.find((it) => label.name === it.name);
|
||||
if (doesExist(flag)) {
|
||||
await syncLabelDiff(options, label, {
|
||||
color: defaultTo(flag.color, label.color),
|
||||
color: colorizeLabel(flag, options.colors),
|
||||
desc: defaultTo(flag.desc, label.desc),
|
||||
name: flag.name,
|
||||
project: options.project,
|
||||
|
@ -152,7 +153,7 @@ export async function syncSingleLabel(options: SyncOptions, label: LabelUpdate):
|
|||
const value = state.values.find((it) => valueName(state, it) === label.name);
|
||||
if (doesExist(value)) {
|
||||
await syncLabelDiff(options, label, {
|
||||
color: defaultTo(value.color, label.color),
|
||||
color: colorizeLabel(state, value, options.colors),
|
||||
desc: defaultTo(value.desc, label.desc),
|
||||
name: valueName(state, value),
|
||||
project: options.project,
|
||||
|
|
12
src/utils.ts
12
src/utils.ts
|
@ -1,4 +1,4 @@
|
|||
import { doesExist, Optional } from '@apextoaster/js-utils';
|
||||
import { doesExist, Optional, mustExist } from '@apextoaster/js-utils';
|
||||
|
||||
export function defaultTo<T>(a: Optional<T>, b: T): T {
|
||||
if (doesExist(a)) {
|
||||
|
@ -7,3 +7,13 @@ export function defaultTo<T>(a: Optional<T>, b: T): T {
|
|||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
export function defaultUntil<T>(...items: Array<Optional<T>>): T {
|
||||
const result = items.reduce(defaultTo, undefined);
|
||||
return mustExist(result);
|
||||
}
|
||||
|
||||
export function randomItem<T>(items: Array<T>, source = Math.random): T {
|
||||
const idx = Math.floor(source() * items.length);
|
||||
return items[idx];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from 'chai';
|
||||
|
||||
import { defaultTo } from '../src/utils';
|
||||
import { defaultTo, defaultUntil } from '../src/utils';
|
||||
|
||||
const TEST_TRUE = 'foo';
|
||||
const TEST_FALSE = 'bar';
|
||||
|
@ -14,4 +14,15 @@ describe('utils', () => {
|
|||
expect(defaultTo(TEST_TRUE, TEST_FALSE)).to.equal(TEST_TRUE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default until value helper', () => {
|
||||
it('should return the first defined value', () => {
|
||||
/* eslint-disable-next-line no-null/no-null */
|
||||
expect(defaultUntil(null, null, TEST_TRUE)).to.equal(TEST_TRUE);
|
||||
/* eslint-disable-next-line no-null/no-null */
|
||||
expect(defaultUntil(null, undefined, TEST_TRUE)).to.equal(TEST_TRUE);
|
||||
expect(defaultUntil(undefined, TEST_TRUE, undefined, undefined, TEST_FALSE)).to.equal(TEST_TRUE);
|
||||
expect(defaultUntil(undefined, undefined, TEST_TRUE, undefined)).to.equal(TEST_TRUE);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue