@ethlete/agent-rules 0.1.0-next.0 → 0.1.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -0
- package/README.md +363 -16
- package/content/git-hooks/post-checkout.sh +10 -0
- package/content/git-hooks/pre-push.sh +5 -0
- package/content/hooks/context-warning.py +430 -0
- package/content/output-styles/ste-clarity.md +131 -0
- package/content/rules/comments.md +50 -20
- package/content/skills/angular-patterns/SKILL.md +1 -1
- package/content/skills/api-source/SKILL.md +118 -0
- package/content/skills/figma-export/SKILL.md +193 -0
- package/content/skills/figma-export/dump-figma-layers.py +83 -0
- package/content/skills/figma-export/dump-figma-svg.py +235 -0
- package/content/skills/figma-export/measure-template.mjs +87 -0
- package/content/skills/git-commit/SKILL.md +6 -7
- package/content/skills/git-flow/SKILL.md +87 -0
- package/content/skills/handoff/SKILL.md +4 -0
- package/content/skills/query/SKILL.md +23 -13
- package/content/skills/rxjs-signals/SKILL.md +1 -1
- package/content/skills/sdk-docs/SKILL.md +10 -2
- package/content/skills/sdk-local-build/SKILL.md +115 -0
- package/content/skills/sdk-source/SKILL.md +133 -0
- package/content/skills/styleguide/STYLEGUIDE.md +2 -2
- package/content/skills/theming/SKILL.md +1 -1
- package/content/skills/timetrack/SKILL.md +66 -0
- package/package.json +12 -1
- package/src/index.js +35 -14
- package/src/index.js.map +1 -1
- package/src/lib/commitlint.d.ts +10 -0
- package/src/lib/commitlint.js +51 -0
- package/src/lib/commitlint.js.map +1 -0
- package/src/lib/config.d.ts +64 -2
- package/src/lib/config.js +54 -9
- package/src/lib/config.js.map +1 -1
- package/src/lib/git-flow/build.d.ts +35 -0
- package/src/lib/git-flow/build.js +24 -0
- package/src/lib/git-flow/build.js.map +1 -0
- package/src/lib/git-flow/config.d.ts +59 -0
- package/src/lib/git-flow/config.js +50 -0
- package/src/lib/git-flow/config.js.map +1 -0
- package/src/lib/git-flow/index.d.ts +6 -0
- package/src/lib/git-flow/index.js +10 -0
- package/src/lib/git-flow/index.js.map +1 -0
- package/src/lib/git-flow/parse.d.ts +49 -0
- package/src/lib/git-flow/parse.js +274 -0
- package/src/lib/git-flow/parse.js.map +1 -0
- package/src/lib/git-flow/rename.d.ts +24 -0
- package/src/lib/git-flow/rename.js +70 -0
- package/src/lib/git-flow/rename.js.map +1 -0
- package/src/lib/git-flow/start.d.ts +49 -0
- package/src/lib/git-flow/start.js +57 -0
- package/src/lib/git-flow/start.js.map +1 -0
- package/src/lib/git-flow/validate.d.ts +34 -0
- package/src/lib/git-flow/validate.js +72 -0
- package/src/lib/git-flow/validate.js.map +1 -0
- package/src/lib/git-flow-command.d.ts +4 -0
- package/src/lib/git-flow-command.js +157 -0
- package/src/lib/git-flow-command.js.map +1 -0
- package/src/lib/git-flow-repair.d.ts +17 -0
- package/src/lib/git-flow-repair.js +146 -0
- package/src/lib/git-flow-repair.js.map +1 -0
- package/src/lib/git-flow-start.d.ts +20 -0
- package/src/lib/git-flow-start.js +132 -0
- package/src/lib/git-flow-start.js.map +1 -0
- package/src/lib/git.d.ts +27 -0
- package/src/lib/git.js +49 -0
- package/src/lib/git.js.map +1 -0
- package/src/lib/gitlab.d.ts +35 -0
- package/src/lib/gitlab.js +98 -0
- package/src/lib/gitlab.js.map +1 -0
- package/src/lib/index.d.ts +2 -0
- package/src/lib/index.js +2 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/migrate.d.ts +6 -0
- package/src/lib/migrate.js +155 -0
- package/src/lib/migrate.js.map +1 -0
- package/src/lib/output-style-command.d.ts +3 -0
- package/src/lib/output-style-command.js +69 -0
- package/src/lib/output-style-command.js.map +1 -0
- package/src/lib/output-style.d.ts +38 -0
- package/src/lib/output-style.js +126 -0
- package/src/lib/output-style.js.map +1 -0
- package/src/lib/owned-paths.js +22 -1
- package/src/lib/owned-paths.js.map +1 -1
- package/src/lib/plan.d.ts +4 -1
- package/src/lib/plan.js +141 -8
- package/src/lib/plan.js.map +1 -1
- package/src/lib/prompt.d.ts +8 -0
- package/src/lib/prompt.js +27 -0
- package/src/lib/prompt.js.map +1 -0
- package/src/lib/render.d.ts +20 -2
- package/src/lib/render.js +31 -8
- package/src/lib/render.js.map +1 -1
- package/src/lib/sync.d.ts +0 -1
- package/src/lib/sync.js +8 -2
- package/src/lib/sync.js.map +1 -1
- package/src/lib/targets/agents-skills.d.ts +8 -0
- package/src/lib/targets/agents-skills.js +18 -0
- package/src/lib/targets/agents-skills.js.map +1 -0
- package/src/lib/targets/claude-hooks.d.ts +11 -0
- package/src/lib/targets/claude-hooks.js +28 -0
- package/src/lib/targets/claude-hooks.js.map +1 -0
- package/src/lib/targets/claude.d.ts +3 -1
- package/src/lib/targets/claude.js +14 -21
- package/src/lib/targets/claude.js.map +1 -1
- package/src/lib/targets/codex-hooks.d.ts +12 -0
- package/src/lib/targets/codex-hooks.js +33 -0
- package/src/lib/targets/codex-hooks.js.map +1 -0
- package/src/lib/targets/codex.d.ts +5 -3
- package/src/lib/targets/codex.js +9 -8
- package/src/lib/targets/codex.js.map +1 -1
- package/src/lib/targets/copilot.d.ts +3 -3
- package/src/lib/targets/copilot.js +6 -29
- package/src/lib/targets/copilot.js.map +1 -1
- package/src/lib/targets/cursor.d.ts +3 -3
- package/src/lib/targets/cursor.js +7 -12
- package/src/lib/targets/cursor.js.map +1 -1
- package/src/lib/targets/git-hooks.d.ts +24 -0
- package/src/lib/targets/git-hooks.js +70 -0
- package/src/lib/targets/git-hooks.js.map +1 -0
- package/src/lib/targets/hooks-shared.d.ts +37 -0
- package/src/lib/targets/hooks-shared.js +95 -0
- package/src/lib/targets/hooks-shared.js.map +1 -0
- package/src/lib/targets/shared.d.ts +22 -13
- package/src/lib/targets/shared.js +32 -15
- package/src/lib/targets/shared.js.map +1 -1
- package/src/lib/timetrack-command.d.ts +11 -0
- package/src/lib/timetrack-command.js +199 -0
- package/src/lib/timetrack-command.js.map +1 -0
- package/src/lib/timetrack.d.ts +86 -0
- package/src/lib/timetrack.js +112 -0
- package/src/lib/timetrack.js.map +1 -0
- package/src/lib/targets/neutral.d.ts +0 -8
- package/src/lib/targets/neutral.js +0 -29
- package/src/lib/targets/neutral.js.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The branch grammar as data: one config drives the parser, the validators, the CLI, the generated
|
|
4
|
+
* skill and `@ethlete/timetrack`'s correlation engine.
|
|
5
|
+
*
|
|
6
|
+
* Nothing in this folder may import `fs`, `path` or `process`, or take a dependency — it is
|
|
7
|
+
* reachable as `@ethlete/agent-rules/git-flow` and gets bundled into a browser webview.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.resolveGitFlowConfig = exports.DEFAULT_GIT_FLOW_CONFIG = exports.GIT_FLOW_RULES = void 0;
|
|
11
|
+
exports.GIT_FLOW_RULES = [
|
|
12
|
+
'unknown-type',
|
|
13
|
+
'missing-key',
|
|
14
|
+
'key-case',
|
|
15
|
+
'missing-subject',
|
|
16
|
+
'type-alias',
|
|
17
|
+
'deprecated-prefix',
|
|
18
|
+
'release-date',
|
|
19
|
+
'wrong-mr-target',
|
|
20
|
+
'protected-push',
|
|
21
|
+
];
|
|
22
|
+
exports.DEFAULT_GIT_FLOW_CONFIG = {
|
|
23
|
+
enforcement: 'advisory',
|
|
24
|
+
subPrefix: 'sub',
|
|
25
|
+
keyPattern: '[A-Z]{2,10}-\\d+',
|
|
26
|
+
keyPrefixes: [],
|
|
27
|
+
baseBranches: { development: 'next', production: 'main' },
|
|
28
|
+
types: ['feat', 'fix', 'refactor', 'chore', 'docs', 'perf', 'test', 'style', 'build', 'ci'],
|
|
29
|
+
typeAliases: { feature: 'feat', bugfix: 'fix' },
|
|
30
|
+
releasePrefix: 'release',
|
|
31
|
+
releasePattern: '\\d{4}\\.\\d{2}\\.\\d{2}',
|
|
32
|
+
hotfixPrefix: 'hotfix',
|
|
33
|
+
subjectCase: 'kebab',
|
|
34
|
+
deprecatedShapes: [{ match: '^dev-(?<subject>.+)$', kind: 'main-feature', renameTo: 'feat/<KEY>-<subject>' }],
|
|
35
|
+
severity: {
|
|
36
|
+
'unknown-type': 'warn',
|
|
37
|
+
'missing-key': 'warn',
|
|
38
|
+
'key-case': 'warn',
|
|
39
|
+
'missing-subject': 'warn',
|
|
40
|
+
'type-alias': 'warn',
|
|
41
|
+
'deprecated-prefix': 'warn',
|
|
42
|
+
'release-date': 'warn',
|
|
43
|
+
'wrong-mr-target': 'warn',
|
|
44
|
+
'protected-push': 'error',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
/** Fills a repo's `gitFlow` config block out to a complete grammar. */
|
|
48
|
+
const resolveGitFlowConfig = (raw) => (Object.assign(Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG), raw), { baseBranches: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.baseBranches), raw === null || raw === void 0 ? void 0 : raw.baseBranches), typeAliases: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.typeAliases), raw === null || raw === void 0 ? void 0 : raw.typeAliases), severity: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.severity), raw === null || raw === void 0 ? void 0 : raw.severity) }));
|
|
49
|
+
exports.resolveGitFlowConfig = resolveGitFlowConfig;
|
|
50
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/config.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEU,QAAA,cAAc,GAAG;IAC5B,cAAc;IACd,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,YAAY;IACZ,mBAAmB;IACnB,cAAc;IACd,iBAAiB;IACjB,gBAAgB;CACR,CAAC;AAiDE,QAAA,uBAAuB,GAAkB;IACpD,WAAW,EAAE,UAAU;IACvB,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,kBAAkB;IAC9B,WAAW,EAAE,EAAE;IACf,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAC3F,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;IAC/C,aAAa,EAAE,SAAS;IACxB,cAAc,EAAE,0BAA0B;IAC1C,YAAY,EAAE,QAAQ;IACtB,WAAW,EAAE,OAAO;IACpB,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IAC7G,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,MAAM;QACrB,UAAU,EAAE,MAAM;QAClB,iBAAiB,EAAE,MAAM;QACzB,YAAY,EAAE,MAAM;QACpB,mBAAmB,EAAE,MAAM;QAC3B,cAAc,EAAE,MAAM;QACtB,iBAAiB,EAAE,MAAM;QACzB,gBAAgB,EAAE,OAAO;KAC1B;CACF,CAAC;AAQF,uEAAuE;AAChE,MAAM,oBAAoB,GAAG,CAAC,GAAsB,EAAiB,EAAE,CAAC,+CAC1E,+BAAuB,GACvB,GAAG,KACN,YAAY,kCAAO,+BAAuB,CAAC,YAAY,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,YAAY,GAC7E,WAAW,kCAAO,+BAAuB,CAAC,WAAW,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,GAC1E,QAAQ,kCAAO,+BAAuB,CAAC,QAAQ,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,KACjE,CAAC;AANU,QAAA,oBAAoB,wBAM9B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./build"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./config"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./parse"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./rename"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./start"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./validate"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,mDAAyB;AACzB,kDAAwB;AACxB,mDAAyB;AACzB,kDAAwB;AACxB,qDAA2B"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GitFlowBranchKind, GitFlowConfig, GitFlowRule } from './config';
|
|
2
|
+
export type GitFlowFinding = {
|
|
3
|
+
rule: GitFlowRule;
|
|
4
|
+
message: string;
|
|
5
|
+
/** The conforming spelling, when it can be derived without asking Jira for an issue key. */
|
|
6
|
+
suggestion?: string;
|
|
7
|
+
};
|
|
8
|
+
export type BranchParseResult = {
|
|
9
|
+
branch: string;
|
|
10
|
+
/** True only for a fully conforming name — an alias or a lowercase key still parses, but is not `ok`. */
|
|
11
|
+
ok: boolean;
|
|
12
|
+
kind: GitFlowBranchKind;
|
|
13
|
+
/** The normalized type segment (`feature/` resolves to `feat`). */
|
|
14
|
+
type?: string;
|
|
15
|
+
storyKey?: string;
|
|
16
|
+
taskKey?: string;
|
|
17
|
+
/** The most specific issue the branch names — what time should be logged against. */
|
|
18
|
+
issueKey?: string;
|
|
19
|
+
subject?: string;
|
|
20
|
+
/** The branch this one nests under, for a sub-feature or a release fix. */
|
|
21
|
+
parent?: string;
|
|
22
|
+
/** The branch matched a `deprecatedShapes` entry, so it should be excluded from adoption reports. */
|
|
23
|
+
deprecated: boolean;
|
|
24
|
+
expectedBase?: string;
|
|
25
|
+
expectedMrTargets: string[];
|
|
26
|
+
/** Set by `resolveThroughBase` when the story key came from the base branch rather than this name. */
|
|
27
|
+
inheritedFrom?: string;
|
|
28
|
+
suggestedName?: string;
|
|
29
|
+
findings: GitFlowFinding[];
|
|
30
|
+
};
|
|
31
|
+
export declare const stripRefPrefix: (ref: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Classifies a branch name against the grammar. Never throws: an unrecognised name comes back as
|
|
34
|
+
* `kind: 'unknown'` with findings, so the validator and timetrack's correlation engine can read
|
|
35
|
+
* the same result for different purposes.
|
|
36
|
+
*/
|
|
37
|
+
export declare const parseBranch: (options: {
|
|
38
|
+
branch: string;
|
|
39
|
+
config: GitFlowConfig;
|
|
40
|
+
}) => BranchParseResult;
|
|
41
|
+
/**
|
|
42
|
+
* Attributes a keyless branch through the branch it is based on. Reviewed branches land in an
|
|
43
|
+
* integration branch, so a flat name like `feat/logout-confirmation` usually has a parent that
|
|
44
|
+
* does carry the story key. Deterministic — no model involved.
|
|
45
|
+
*/
|
|
46
|
+
export declare const resolveThroughBase: (options: {
|
|
47
|
+
branch: BranchParseResult;
|
|
48
|
+
base: BranchParseResult;
|
|
49
|
+
}) => BranchParseResult;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveThroughBase = exports.parseBranch = exports.stripRefPrefix = void 0;
|
|
4
|
+
const build_1 = require("./build");
|
|
5
|
+
const stripRefPrefix = (ref) => ref
|
|
6
|
+
.trim()
|
|
7
|
+
.replace(/^refs\/heads\//, '')
|
|
8
|
+
.replace(/^refs\/remotes\/[^/]+\//, '');
|
|
9
|
+
exports.stripRefPrefix = stripRefPrefix;
|
|
10
|
+
/**
|
|
11
|
+
* The key is only recognised anchored at the start of a segment. A trailing number is therefore
|
|
12
|
+
* never mistaken for one — `ratings-reveal-secondary-page-27` yields no key rather than a wrong
|
|
13
|
+
* one, and a confidently wrong attribution is worse than none.
|
|
14
|
+
*/
|
|
15
|
+
const parseSegment = (options) => {
|
|
16
|
+
const { segment, config, role } = options;
|
|
17
|
+
const match = new RegExp(`^(${config.keyPattern})(?:-(.*))?$`, 'i').exec(segment);
|
|
18
|
+
const rawKey = match === null || match === void 0 ? void 0 : match[1];
|
|
19
|
+
const known = config.keyPrefixes.length === 0 ||
|
|
20
|
+
config.keyPrefixes.some((prefix) => rawKey === null || rawKey === void 0 ? void 0 : rawKey.toUpperCase().startsWith(prefix.toUpperCase()));
|
|
21
|
+
if (!rawKey || !known) {
|
|
22
|
+
return {
|
|
23
|
+
subject: segment || undefined,
|
|
24
|
+
findings: [{ rule: 'missing-key', message: `"${segment}" carries no ${role} issue key.` }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const key = rawKey.toUpperCase();
|
|
28
|
+
const subject = (match === null || match === void 0 ? void 0 : match[2]) || undefined;
|
|
29
|
+
const findings = [];
|
|
30
|
+
if (rawKey !== key) {
|
|
31
|
+
findings.push({ rule: 'key-case', message: `Issue key "${rawKey}" should be uppercase "${key}".` });
|
|
32
|
+
}
|
|
33
|
+
if (!subject) {
|
|
34
|
+
findings.push({ rule: 'missing-subject', message: `"${segment}" names ${key} but has no subject.` });
|
|
35
|
+
}
|
|
36
|
+
return { key, subject, findings };
|
|
37
|
+
};
|
|
38
|
+
const matchDeprecatedShape = (options) => {
|
|
39
|
+
var _a;
|
|
40
|
+
const { branch, config } = options;
|
|
41
|
+
for (const shape of config.deprecatedShapes) {
|
|
42
|
+
const match = new RegExp(shape.match).exec(branch);
|
|
43
|
+
if (match)
|
|
44
|
+
return { shape, groups: (_a = match.groups) !== null && _a !== void 0 ? _a : {} };
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
};
|
|
48
|
+
const renameSuggestion = (options) => {
|
|
49
|
+
var _a;
|
|
50
|
+
const { shape, groups } = options;
|
|
51
|
+
const key = groups['key'];
|
|
52
|
+
return shape.renameTo
|
|
53
|
+
.replace(/<subject>/g, (_a = groups['subject']) !== null && _a !== void 0 ? _a : '')
|
|
54
|
+
.replace(/<KEY>/g, key ? key.toUpperCase() : '<KEY>');
|
|
55
|
+
};
|
|
56
|
+
const targetsForKind = (options) => {
|
|
57
|
+
const { kind, config, parent, branch } = options;
|
|
58
|
+
const { development, production } = config.baseBranches;
|
|
59
|
+
switch (kind) {
|
|
60
|
+
case 'main-feature':
|
|
61
|
+
return { expectedBase: development, expectedMrTargets: [development] };
|
|
62
|
+
case 'sub-feature':
|
|
63
|
+
case 'release-fix':
|
|
64
|
+
return { expectedBase: parent, expectedMrTargets: parent ? [parent] : [] };
|
|
65
|
+
case 'release':
|
|
66
|
+
return { expectedBase: development, expectedMrTargets: [development, production] };
|
|
67
|
+
case 'hotfix':
|
|
68
|
+
return { expectedBase: production, expectedMrTargets: [production] };
|
|
69
|
+
case 'protected':
|
|
70
|
+
return { expectedMrTargets: branch === development ? [production] : [development] };
|
|
71
|
+
default:
|
|
72
|
+
return { expectedMrTargets: [] };
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Classifies a branch name against the grammar. Never throws: an unrecognised name comes back as
|
|
77
|
+
* `kind: 'unknown'` with findings, so the validator and timetrack's correlation engine can read
|
|
78
|
+
* the same result for different purposes.
|
|
79
|
+
*/
|
|
80
|
+
const parseBranch = (options) => {
|
|
81
|
+
const { config } = options;
|
|
82
|
+
const branch = (0, exports.stripRefPrefix)(options.branch);
|
|
83
|
+
const segments = branch.split('/');
|
|
84
|
+
const unknown = (message) => ({
|
|
85
|
+
branch,
|
|
86
|
+
ok: false,
|
|
87
|
+
kind: 'unknown',
|
|
88
|
+
deprecated: false,
|
|
89
|
+
expectedMrTargets: [],
|
|
90
|
+
findings: [{ rule: 'unknown-type', message }],
|
|
91
|
+
});
|
|
92
|
+
if (!branch || segments.some((segment) => !segment))
|
|
93
|
+
return unknown(`"${options.branch}" is not a branch name.`);
|
|
94
|
+
if (branch === config.baseBranches.development || branch === config.baseBranches.production) {
|
|
95
|
+
return Object.assign({ branch, ok: true, kind: 'protected', deprecated: false, findings: [] }, targetsForKind({ kind: 'protected', config, branch }));
|
|
96
|
+
}
|
|
97
|
+
const deprecated = matchDeprecatedShape({ branch, config });
|
|
98
|
+
if (deprecated) {
|
|
99
|
+
const suggestion = renameSuggestion(deprecated);
|
|
100
|
+
return Object.assign({ branch, ok: false, kind: deprecated.shape.kind, subject: deprecated.groups['subject'], deprecated: true, suggestedName: suggestion, findings: [
|
|
101
|
+
{
|
|
102
|
+
rule: 'deprecated-prefix',
|
|
103
|
+
message: `"${branch}" uses a deprecated spelling; rename it to ${suggestion}.`,
|
|
104
|
+
suggestion,
|
|
105
|
+
},
|
|
106
|
+
] }, targetsForKind({ kind: deprecated.shape.kind, config }));
|
|
107
|
+
}
|
|
108
|
+
const [prefix, ...rest] = segments;
|
|
109
|
+
if (prefix === config.subPrefix)
|
|
110
|
+
return dropRedundantSuggestion(parseNested({ branch, segments: rest, config }));
|
|
111
|
+
if (prefix === config.releasePrefix)
|
|
112
|
+
return dropRedundantSuggestion(parseRelease({ branch, segments: rest, config }));
|
|
113
|
+
if (prefix === config.hotfixPrefix)
|
|
114
|
+
return dropRedundantSuggestion(parseHotfix({ branch, segments: rest, config }));
|
|
115
|
+
return dropRedundantSuggestion(parseFeature({ branch, prefix: prefix !== null && prefix !== void 0 ? prefix : '', segments: rest, config }));
|
|
116
|
+
};
|
|
117
|
+
exports.parseBranch = parseBranch;
|
|
118
|
+
const unrecognised = (options) => ({
|
|
119
|
+
branch: options.branch,
|
|
120
|
+
ok: false,
|
|
121
|
+
kind: 'unknown',
|
|
122
|
+
deprecated: false,
|
|
123
|
+
expectedMrTargets: [],
|
|
124
|
+
findings: [{ rule: 'unknown-type', message: options.message }],
|
|
125
|
+
});
|
|
126
|
+
/**
|
|
127
|
+
* `sub/<parent path>/<KEY>-<subject>` — the nested shape. The parent's full name is inside the
|
|
128
|
+
* child's, so the merge request target needs no lookup; only two levels are allowed, so a parent
|
|
129
|
+
* that is itself nested is not a shape.
|
|
130
|
+
*/
|
|
131
|
+
const parseNested = (options) => {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const { branch, segments, config } = options;
|
|
134
|
+
const leaf = segments[segments.length - 1];
|
|
135
|
+
const parent = segments.slice(0, -1).join('/');
|
|
136
|
+
if (!leaf || !parent) {
|
|
137
|
+
return unrecognised({ branch, message: `"${branch}" names no parent branch to nest under.` });
|
|
138
|
+
}
|
|
139
|
+
const parentParse = (0, exports.parseBranch)({ branch: parent, config });
|
|
140
|
+
const kind = nestedKindFor(parentParse);
|
|
141
|
+
if (!kind) {
|
|
142
|
+
return unrecognised({
|
|
143
|
+
branch,
|
|
144
|
+
message: `"${parent}" is not a branch anything can nest under — only a main feature or a release branch is.`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const parts = parseSegment({ segment: leaf, config, role: kind === 'release-fix' ? 'bug' : 'task' });
|
|
148
|
+
const findings = [...parentParse.findings, ...parts.findings];
|
|
149
|
+
return Object.assign({ branch, ok: findings.length === 0, type: parentParse.type, kind, storyKey: parentParse.storyKey, taskKey: parts.key, issueKey: (_a = parts.key) !== null && _a !== void 0 ? _a : parentParse.storyKey, subject: parts.subject, parent, deprecated: false, findings, suggestedName: parts.key
|
|
150
|
+
? (0, build_1.buildBranchName)({
|
|
151
|
+
spec: { kind, parent: (_b = parentParse.suggestedName) !== null && _b !== void 0 ? _b : parent, key: parts.key, subject: (_c = parts.subject) !== null && _c !== void 0 ? _c : '' },
|
|
152
|
+
config,
|
|
153
|
+
})
|
|
154
|
+
: undefined }, targetsForKind({ kind, config, parent }));
|
|
155
|
+
};
|
|
156
|
+
const nestedKindFor = (parent) => {
|
|
157
|
+
if (parent.kind === 'release')
|
|
158
|
+
return 'release-fix';
|
|
159
|
+
return parent.kind === 'main-feature' && !parent.deprecated ? 'sub-feature' : undefined;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* The spelling the convention was originally written with, `<parent>/<KEY>-<subject>`. It parses so
|
|
163
|
+
* that `explain` and `repair` can say something useful about it, but it can never exist next to the
|
|
164
|
+
* parent it names — see `subPrefix`.
|
|
165
|
+
*/
|
|
166
|
+
const nestedTooDeep = (options) => {
|
|
167
|
+
var _a, _b;
|
|
168
|
+
const { branch, kind, parent, leaf, config, storyKey, type } = options;
|
|
169
|
+
const suggestion = leaf.key
|
|
170
|
+
? (0, build_1.buildBranchName)({ spec: { kind, parent, key: leaf.key, subject: (_a = leaf.subject) !== null && _a !== void 0 ? _a : '' }, config })
|
|
171
|
+
: `${config.subPrefix}/${branch}`;
|
|
172
|
+
return Object.assign({ branch, ok: false, kind,
|
|
173
|
+
type,
|
|
174
|
+
storyKey, taskKey: leaf.key, issueKey: (_b = leaf.key) !== null && _b !== void 0 ? _b : storyKey, subject: leaf.subject, parent, deprecated: true, suggestedName: suggestion, findings: [
|
|
175
|
+
{
|
|
176
|
+
rule: 'deprecated-prefix',
|
|
177
|
+
message: `"${branch}" cannot exist while ${parent} does — git rejects a ref that is both a branch and a directory of branches. Use ${suggestion}.`,
|
|
178
|
+
suggestion,
|
|
179
|
+
},
|
|
180
|
+
] }, targetsForKind({ kind, config, parent }));
|
|
181
|
+
};
|
|
182
|
+
const dropRedundantSuggestion = (result) => result.suggestedName === result.branch ? Object.assign(Object.assign({}, result), { suggestedName: undefined }) : result;
|
|
183
|
+
const parseRelease = (options) => {
|
|
184
|
+
const { branch, segments, config } = options;
|
|
185
|
+
const [date, leaf, ...extra] = segments;
|
|
186
|
+
if (!date || extra.length > 0) {
|
|
187
|
+
return unrecognised({ branch, message: `"${branch}" is not a release or release-fix branch.` });
|
|
188
|
+
}
|
|
189
|
+
const findings = [];
|
|
190
|
+
if (!new RegExp(`^${config.releasePattern}$`).test(date)) {
|
|
191
|
+
findings.push({ rule: 'release-date', message: `"${date}" is not a release date (expected YYYY.MM.DD).` });
|
|
192
|
+
}
|
|
193
|
+
const parent = `${config.releasePrefix}/${date}`;
|
|
194
|
+
if (leaf === undefined) {
|
|
195
|
+
return Object.assign({ branch, ok: findings.length === 0, kind: 'release', deprecated: false, findings }, targetsForKind({ kind: 'release', config }));
|
|
196
|
+
}
|
|
197
|
+
return nestedTooDeep({
|
|
198
|
+
branch,
|
|
199
|
+
kind: 'release-fix',
|
|
200
|
+
parent,
|
|
201
|
+
leaf: parseSegment({ segment: leaf, config, role: 'bug' }),
|
|
202
|
+
config,
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
const parseHotfix = (options) => {
|
|
206
|
+
var _a;
|
|
207
|
+
const { branch, segments, config } = options;
|
|
208
|
+
const [leaf, ...extra] = segments;
|
|
209
|
+
if (!leaf || extra.length > 0) {
|
|
210
|
+
return {
|
|
211
|
+
branch,
|
|
212
|
+
ok: false,
|
|
213
|
+
kind: 'unknown',
|
|
214
|
+
deprecated: false,
|
|
215
|
+
expectedMrTargets: [],
|
|
216
|
+
findings: [{ rule: 'unknown-type', message: `"${branch}" is not a hotfix branch.` }],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const parts = parseSegment({ segment: leaf, config, role: 'bug' });
|
|
220
|
+
return Object.assign({ branch, ok: parts.findings.length === 0, kind: 'hotfix', taskKey: parts.key, issueKey: parts.key, subject: parts.subject, deprecated: false, findings: parts.findings, suggestedName: parts.key
|
|
221
|
+
? (0, build_1.buildBranchName)({ spec: { kind: 'hotfix', key: parts.key, subject: (_a = parts.subject) !== null && _a !== void 0 ? _a : '' }, config })
|
|
222
|
+
: undefined }, targetsForKind({ kind: 'hotfix', config }));
|
|
223
|
+
};
|
|
224
|
+
const parseFeature = (options) => {
|
|
225
|
+
var _a;
|
|
226
|
+
const { branch, prefix, segments, config } = options;
|
|
227
|
+
const alias = config.typeAliases[prefix];
|
|
228
|
+
const type = config.types.includes(prefix) ? prefix : alias;
|
|
229
|
+
const [story, task, ...extra] = segments;
|
|
230
|
+
if (!type || !story || extra.length > 0) {
|
|
231
|
+
return unrecognised({
|
|
232
|
+
branch,
|
|
233
|
+
message: `"${branch}" matches no branch shape; expected <type>/<KEY>-<subject> with type one of ${config.types.join(', ')}.`,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const findings = [];
|
|
237
|
+
if (alias && prefix !== type) {
|
|
238
|
+
findings.push({ rule: 'type-alias', message: `"${prefix}/" is an alias; use "${type}/".` });
|
|
239
|
+
}
|
|
240
|
+
const storyParts = parseSegment({ segment: story, config, role: 'story' });
|
|
241
|
+
if (task === undefined) {
|
|
242
|
+
findings.push(...storyParts.findings);
|
|
243
|
+
return Object.assign({ branch, ok: findings.length === 0, kind: 'main-feature', type, storyKey: storyParts.key, issueKey: storyParts.key, subject: storyParts.subject, deprecated: false, findings, suggestedName: storyParts.key
|
|
244
|
+
? (0, build_1.buildBranchName)({
|
|
245
|
+
spec: { kind: 'main-feature', type, key: storyParts.key, subject: (_a = storyParts.subject) !== null && _a !== void 0 ? _a : '' },
|
|
246
|
+
config,
|
|
247
|
+
})
|
|
248
|
+
: undefined }, targetsForKind({ kind: 'main-feature', config }));
|
|
249
|
+
}
|
|
250
|
+
return nestedTooDeep({
|
|
251
|
+
branch,
|
|
252
|
+
kind: 'sub-feature',
|
|
253
|
+
parent: `${prefix}/${story}`,
|
|
254
|
+
leaf: parseSegment({ segment: task, config, role: 'task' }),
|
|
255
|
+
config,
|
|
256
|
+
storyKey: storyParts.key,
|
|
257
|
+
type,
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Attributes a keyless branch through the branch it is based on. Reviewed branches land in an
|
|
262
|
+
* integration branch, so a flat name like `feat/logout-confirmation` usually has a parent that
|
|
263
|
+
* does carry the story key. Deterministic — no model involved.
|
|
264
|
+
*/
|
|
265
|
+
const resolveThroughBase = (options) => {
|
|
266
|
+
var _a, _b;
|
|
267
|
+
const { branch, base } = options;
|
|
268
|
+
const inherited = (_a = base.storyKey) !== null && _a !== void 0 ? _a : base.taskKey;
|
|
269
|
+
if (branch.storyKey || !inherited)
|
|
270
|
+
return branch;
|
|
271
|
+
return Object.assign(Object.assign({}, branch), { storyKey: inherited, issueKey: (_b = branch.taskKey) !== null && _b !== void 0 ? _b : inherited, inheritedFrom: base.branch });
|
|
272
|
+
};
|
|
273
|
+
exports.resolveThroughBase = resolveThroughBase;
|
|
274
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GitFlowConfig } from './config';
|
|
2
|
+
export type ConformingName = {
|
|
3
|
+
ok: true;
|
|
4
|
+
name: string;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
/**
|
|
8
|
+
* `needs-key` is the only reason a caller can act on: file the issue, then ask again with the
|
|
9
|
+
* key it returned.
|
|
10
|
+
*/
|
|
11
|
+
reason: 'already-conforms' | 'needs-key' | 'no-shape';
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The conforming name a non-conforming branch should take, once an issue key exists for it.
|
|
15
|
+
*
|
|
16
|
+
* A candidate is returned only after it parses as fully conforming, so a rename always lands on a
|
|
17
|
+
* name the grammar accepts — `parseBranch`'s own `suggestedName` does not guarantee that for a
|
|
18
|
+
* nested branch whose leaf names no issue, and half a rename is worse than none.
|
|
19
|
+
*/
|
|
20
|
+
export declare const conformingNameFor: (options: {
|
|
21
|
+
branch: string;
|
|
22
|
+
key?: string;
|
|
23
|
+
config: GitFlowConfig;
|
|
24
|
+
}) => ConformingName;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.conformingNameFor = void 0;
|
|
4
|
+
const build_1 = require("./build");
|
|
5
|
+
const parse_1 = require("./parse");
|
|
6
|
+
const KEY_PLACEHOLDER = '<KEY>';
|
|
7
|
+
/**
|
|
8
|
+
* The spec that rebuilds a branch whose leaf carries no key at all, which is why `parseBranch` left
|
|
9
|
+
* `suggestedName` unset. Only the kinds the grammar can spell are here — an unrecognised name names
|
|
10
|
+
* no kind, and inventing one would rename the branch to something the user never chose.
|
|
11
|
+
*/
|
|
12
|
+
const specFor = (options) => {
|
|
13
|
+
var _a;
|
|
14
|
+
const { parse, key } = options;
|
|
15
|
+
const subject = (_a = parse.subject) !== null && _a !== void 0 ? _a : '';
|
|
16
|
+
switch (parse.kind) {
|
|
17
|
+
case 'main-feature':
|
|
18
|
+
return { kind: 'main-feature', type: parse.type, key, subject };
|
|
19
|
+
case 'hotfix':
|
|
20
|
+
return { kind: 'hotfix', key, subject };
|
|
21
|
+
case 'sub-feature':
|
|
22
|
+
return parse.parent ? { kind: 'sub-feature', parent: parse.parent, key, subject } : undefined;
|
|
23
|
+
case 'release-fix':
|
|
24
|
+
return parse.parent ? { kind: 'release-fix', parent: parse.parent, key, subject } : undefined;
|
|
25
|
+
default:
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const candidatesFor = (options) => {
|
|
30
|
+
const { parse, key, config } = options;
|
|
31
|
+
const suggested = parse.suggestedName;
|
|
32
|
+
const candidates = [];
|
|
33
|
+
if (suggested && !suggested.includes(KEY_PLACEHOLDER))
|
|
34
|
+
candidates.push(suggested);
|
|
35
|
+
if (key) {
|
|
36
|
+
if (suggested === null || suggested === void 0 ? void 0 : suggested.includes(KEY_PLACEHOLDER))
|
|
37
|
+
candidates.push(suggested.replace(/<KEY>/g, key.toUpperCase()));
|
|
38
|
+
const spec = specFor({ parse, key: key.toUpperCase() });
|
|
39
|
+
if (spec)
|
|
40
|
+
candidates.push((0, build_1.buildBranchName)({ spec, config }));
|
|
41
|
+
}
|
|
42
|
+
return candidates;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The conforming name a non-conforming branch should take, once an issue key exists for it.
|
|
46
|
+
*
|
|
47
|
+
* A candidate is returned only after it parses as fully conforming, so a rename always lands on a
|
|
48
|
+
* name the grammar accepts — `parseBranch`'s own `suggestedName` does not guarantee that for a
|
|
49
|
+
* nested branch whose leaf names no issue, and half a rename is worse than none.
|
|
50
|
+
*/
|
|
51
|
+
const conformingNameFor = (options) => {
|
|
52
|
+
var _a;
|
|
53
|
+
const { key, config } = options;
|
|
54
|
+
const parse = (0, parse_1.parseBranch)({ branch: options.branch, config });
|
|
55
|
+
if (parse.ok)
|
|
56
|
+
return { ok: false, reason: 'already-conforms' };
|
|
57
|
+
for (const name of candidatesFor({ parse, key, config })) {
|
|
58
|
+
if (name !== parse.branch && (0, parse_1.parseBranch)({ branch: name, config }).ok)
|
|
59
|
+
return { ok: true, name };
|
|
60
|
+
}
|
|
61
|
+
if (key)
|
|
62
|
+
return { ok: false, reason: 'no-shape' };
|
|
63
|
+
// Whether a key would help is answered by trying one, using a prefix this repo accepts so the
|
|
64
|
+
// probe is not rejected by `keyPrefixes` for a reason the real key would not hit.
|
|
65
|
+
const probe = candidatesFor({ parse, key: `${(_a = config.keyPrefixes[0]) !== null && _a !== void 0 ? _a : 'KEY'}-1`, config });
|
|
66
|
+
const rebuildable = probe.some((name) => (0, parse_1.parseBranch)({ branch: name, config }).ok);
|
|
67
|
+
return { ok: false, reason: rebuildable ? 'needs-key' : 'no-shape' };
|
|
68
|
+
};
|
|
69
|
+
exports.conformingNameFor = conformingNameFor;
|
|
70
|
+
//# sourceMappingURL=rename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/rename.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BranchNameSpec } from './build';
|
|
2
|
+
import { GitFlowConfig } from './config';
|
|
3
|
+
import { BranchParseResult } from './parse';
|
|
4
|
+
export type StartPlan = {
|
|
5
|
+
branch: string;
|
|
6
|
+
/** The branch to create the new one from. Absent only when `problems` says why. */
|
|
7
|
+
base?: string;
|
|
8
|
+
mrTargets: string[];
|
|
9
|
+
parse: BranchParseResult;
|
|
10
|
+
/** Empty when the plan is safe to execute; every entry is a reason to refuse. */
|
|
11
|
+
problems: string[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The plan a caller must show before it writes anything: the branch name, the base to branch from
|
|
15
|
+
* and the merge request target. Built through `buildBranchName` and then re-parsed, so a spec the
|
|
16
|
+
* grammar cannot express — a key the project's prefixes reject, a parent that is itself
|
|
17
|
+
* non-conforming — comes back as a problem instead of as a branch somebody has to delete again.
|
|
18
|
+
*/
|
|
19
|
+
export declare const planStart: (options: {
|
|
20
|
+
spec: BranchNameSpec;
|
|
21
|
+
config: GitFlowConfig;
|
|
22
|
+
}) => StartPlan;
|
|
23
|
+
/**
|
|
24
|
+
* The spec for a branch nesting under `parent`. Which of the two nested kinds it is follows from the
|
|
25
|
+
* parent alone, so no caller has to decide it: a release branch takes fixes, anything else takes
|
|
26
|
+
* sub-features.
|
|
27
|
+
*/
|
|
28
|
+
export declare const nestedSpecFor: (options: {
|
|
29
|
+
parent: string;
|
|
30
|
+
key: string;
|
|
31
|
+
subject: string;
|
|
32
|
+
config: GitFlowConfig;
|
|
33
|
+
}) => BranchNameSpec;
|
|
34
|
+
/**
|
|
35
|
+
* The branches a story's sub-features may nest under, out of a list of names.
|
|
36
|
+
*
|
|
37
|
+
* A sub-feature's parent is a branch name and not an issue, because the nested spelling keeps the
|
|
38
|
+
* parent's full path inside the child's — so this, and not a Jira lookup, is what says whether a
|
|
39
|
+
* Task can be started at all. A deprecated spelling is never a candidate: a child nested under a
|
|
40
|
+
* name that is about to be repaired would have to be renamed with it.
|
|
41
|
+
*
|
|
42
|
+
* More than one match is returned rather than resolved. Which of two feature branches a story means
|
|
43
|
+
* is not something a grammar can answer, and picking one would put the work on the wrong branch.
|
|
44
|
+
*/
|
|
45
|
+
export declare const featureBranchesFor: (options: {
|
|
46
|
+
branches: readonly string[];
|
|
47
|
+
storyKey: string;
|
|
48
|
+
config: GitFlowConfig;
|
|
49
|
+
}) => string[];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.featureBranchesFor = exports.nestedSpecFor = exports.planStart = void 0;
|
|
4
|
+
const build_1 = require("./build");
|
|
5
|
+
const parse_1 = require("./parse");
|
|
6
|
+
/**
|
|
7
|
+
* The plan a caller must show before it writes anything: the branch name, the base to branch from
|
|
8
|
+
* and the merge request target. Built through `buildBranchName` and then re-parsed, so a spec the
|
|
9
|
+
* grammar cannot express — a key the project's prefixes reject, a parent that is itself
|
|
10
|
+
* non-conforming — comes back as a problem instead of as a branch somebody has to delete again.
|
|
11
|
+
*/
|
|
12
|
+
const planStart = (options) => {
|
|
13
|
+
const { spec, config } = options;
|
|
14
|
+
const branch = (0, build_1.buildBranchName)({ spec, config });
|
|
15
|
+
const parse = (0, parse_1.parseBranch)({ branch, config });
|
|
16
|
+
const problems = [
|
|
17
|
+
...(parse.kind === spec.kind ? [] : [`"${branch}" parses as ${parse.kind}, not ${spec.kind}.`]),
|
|
18
|
+
...parse.findings.map((finding) => finding.message),
|
|
19
|
+
...(parse.expectedBase ? [] : [`"${branch}" has no base branch to branch from.`]),
|
|
20
|
+
];
|
|
21
|
+
return { branch, base: parse.expectedBase, mrTargets: parse.expectedMrTargets, parse, problems };
|
|
22
|
+
};
|
|
23
|
+
exports.planStart = planStart;
|
|
24
|
+
/**
|
|
25
|
+
* The spec for a branch nesting under `parent`. Which of the two nested kinds it is follows from the
|
|
26
|
+
* parent alone, so no caller has to decide it: a release branch takes fixes, anything else takes
|
|
27
|
+
* sub-features.
|
|
28
|
+
*/
|
|
29
|
+
const nestedSpecFor = (options) => {
|
|
30
|
+
const { parent, key, subject, config } = options;
|
|
31
|
+
const kind = (0, parse_1.parseBranch)({ branch: parent, config }).kind === 'release' ? 'release-fix' : 'sub-feature';
|
|
32
|
+
return { kind, parent, key, subject };
|
|
33
|
+
};
|
|
34
|
+
exports.nestedSpecFor = nestedSpecFor;
|
|
35
|
+
/**
|
|
36
|
+
* The branches a story's sub-features may nest under, out of a list of names.
|
|
37
|
+
*
|
|
38
|
+
* A sub-feature's parent is a branch name and not an issue, because the nested spelling keeps the
|
|
39
|
+
* parent's full path inside the child's — so this, and not a Jira lookup, is what says whether a
|
|
40
|
+
* Task can be started at all. A deprecated spelling is never a candidate: a child nested under a
|
|
41
|
+
* name that is about to be repaired would have to be renamed with it.
|
|
42
|
+
*
|
|
43
|
+
* More than one match is returned rather than resolved. Which of two feature branches a story means
|
|
44
|
+
* is not something a grammar can answer, and picking one would put the work on the wrong branch.
|
|
45
|
+
*/
|
|
46
|
+
const featureBranchesFor = (options) => {
|
|
47
|
+
const { branches, config } = options;
|
|
48
|
+
const storyKey = options.storyKey.toUpperCase();
|
|
49
|
+
return [...new Set(branches.map(parse_1.stripRefPrefix))]
|
|
50
|
+
.filter((branch) => {
|
|
51
|
+
const parse = (0, parse_1.parseBranch)({ branch, config });
|
|
52
|
+
return parse.kind === 'main-feature' && !parse.deprecated && parse.storyKey === storyKey;
|
|
53
|
+
})
|
|
54
|
+
.sort();
|
|
55
|
+
};
|
|
56
|
+
exports.featureBranchesFor = featureBranchesFor;
|
|
57
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/start.ts"],"names":[],"mappings":";;;AAAA,mCAA0D;AAE1D,mCAAyE;AAYzE;;;;;GAKG;AACI,MAAM,SAAS,GAAG,CAAC,OAAwD,EAAa,EAAE;IAC/F,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,uBAAe,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG;QACf,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,eAAe,KAAK,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAC/F,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,sCAAsC,CAAC,CAAC;KAClF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACnG,CAAC,CAAC;AAZW,QAAA,SAAS,aAYpB;AAEF;;;;GAIG;AACI,MAAM,aAAa,GAAG,CAAC,OAK7B,EAAkB,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACjD,MAAM,IAAI,GAAG,IAAA,mBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;IAExG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC,CAAC;AAVW,QAAA,aAAa,iBAUxB;AAEF;;;;;;;;;;GAUG;AACI,MAAM,kBAAkB,GAAG,CAAC,OAIlC,EAAE,EAAE;IACH,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAEhD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,sBAAc,CAAC,CAAC,CAAC;SAC9C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9C,OAAO,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC3F,CAAC,CAAC;SACD,IAAI,EAAE,CAAC;AACZ,CAAC,CAAC;AAfW,QAAA,kBAAkB,sBAe7B"}
|