autoforce 0.1.11 → 0.1.12
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 +29 -0
- package/README.md +0 -13
- package/commands/modelA/tasks/list.json +1 -1
- package/commands/modelC/new/issue.json +6 -23
- package/commands/modelC/tasks/list.json +3 -1
- package/commands/modelC/tasks/publish.json +2 -1
- package/lib/auto.js +3 -3
- package/lib/helpers/context.d.ts +14 -1
- package/lib/helpers/context.js +70 -16
- package/lib/helpers/github-graphql.d.ts +2 -33
- package/lib/helpers/github-graphql.js +50 -50
- package/lib/helpers/github-project-graphql.d.ts +37 -5
- package/lib/helpers/github-project-graphql.js +81 -15
- package/lib/helpers/gitlab-graphql.d.ts +4 -2
- package/lib/helpers/gitlab-graphql.js +12 -2
- package/lib/helpers/taskFunctions.js +101 -35
- package/lib/helpers/tasks.js +6 -2
- package/lib/helpers/template.d.ts +2 -1
- package/lib/helpers/template.js +20 -3
- package/lib/helpers/util.d.ts +3 -2
- package/lib/helpers/util.js +64 -17
- package/package.json +1 -1
- package/templates/modelB/changelog.md +8 -4
- package/templates/modelB/openIssues.bash +4 -0
- package/templates/modelB/viewIssue.bash +8 -0
- package/templates/modelB/openIssues.md +0 -0
package/CHANGELOG.md
CHANGED
@@ -1,7 +1,35 @@
|
|
1
1
|
# Versiones
|
2
2
|
|
3
|
+
## Version 0.1.12
|
4
|
+
- Fecha: 28/11/2024
|
5
|
+
- Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.10)
|
6
|
+
- Cambios:
|
7
|
+
|
8
|
+
* [Publish] ponga en Changelog todos los issues Closed del milestone asociado. Y los mueva al final de todo a la Columna "Published"
|
9
|
+
- https://github.com/sebastianclaros/autoforce/issues/11
|
10
|
+
* [List] Poner Filtros: Abiertos Mios, Por Label, Por Milestone
|
11
|
+
- https://github.com/sebastianclaros/autoforce/issues/17
|
12
|
+
* [List] Guardar en autoforce el list default list template y default list Filter
|
13
|
+
- https://github.com/sebastianclaros/autoforce/issues/18
|
14
|
+
* [new Issue] Agregar Milestone
|
15
|
+
- https://github.com/sebastianclaros/autoforce/issues/19
|
16
|
+
* [config] dividir config general en config por comandos
|
17
|
+
- https://github.com/sebastianclaros/autoforce/issues/27
|
18
|
+
* [list] que tome de los argumentos valores.
|
19
|
+
- https://github.com/sebastianclaros/autoforce/issues/28
|
20
|
+
* [list] que reciba argumentos en taskFunctions y que tome orden de precedencia parametros de funcion, argumentos de comando y por ultimo autoforce.json
|
21
|
+
- https://github.com/sebastianclaros/autoforce/issues/29
|
22
|
+
* [new] que el milestone sea opcional
|
23
|
+
- https://github.com/sebastianclaros/autoforce/issues/30
|
24
|
+
## Version 0.1.11
|
25
|
+
- Fecha: 29/11/2024
|
26
|
+
- Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.11)
|
27
|
+
- Cambios:
|
28
|
+
* [comando config lea del autoforce.json](https://github.com/sebastianclaros/autoforce/issues/4)
|
29
|
+
|
3
30
|
## Version 0.1.10
|
4
31
|
- Fecha: 28/11/2024
|
32
|
+
- Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.10)
|
5
33
|
- Cambios:
|
6
34
|
* [publish deberia pedir la version, y asignarla en el autoforce version](https://github.com/sebastianclaros/autoforce/issues/12)
|
7
35
|
* [Models en config que lea un json descriptivo](https://github.com/sebastianclaros/autoforce/issues/9)
|
@@ -16,6 +44,7 @@
|
|
16
44
|
|
17
45
|
## Version 0.1.9
|
18
46
|
|
47
|
+
- Paquete: [Descargar](https://www.npmjs.com/package/autoforce/v/0.1.9)
|
19
48
|
- Cambios:
|
20
49
|
* Comando de new issue para crear un issue nuevo en el backlog
|
21
50
|
* Comando de list para ver issues en backlog o ver los detalles de uno
|
package/README.md
CHANGED
@@ -60,19 +60,6 @@ En este repo las tareas buscan automatizar o integrar el siguiente tipo gestione
|
|
60
60
|
|
61
61
|
|
62
62
|
|
63
|
-
## Instalación
|
64
|
-
|
65
|
-
```
|
66
|
-
yarn add -D autoforce
|
67
|
-
```
|
68
|
-
|
69
|
-
Chequear instalacion
|
70
|
-
|
71
|
-
```
|
72
|
-
npx autoforce version
|
73
|
-
```
|
74
|
-
|
75
|
-
|
76
63
|
## Usos
|
77
64
|
Una vez instalado se puede crear scripts a medida o bien ejecutar
|
78
65
|
|
@@ -5,28 +5,11 @@
|
|
5
5
|
"title": { "required": true },
|
6
6
|
"label": {
|
7
7
|
"type": "select",
|
8
|
-
"
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
},
|
14
|
-
{
|
15
|
-
"title": "Bugfix",
|
16
|
-
"value": "bug",
|
17
|
-
"description": "Correxion de codigo, no hay incremento funcional"
|
18
|
-
},
|
19
|
-
{
|
20
|
-
"title": "Documentation",
|
21
|
-
"value": "documentation",
|
22
|
-
"description": "Cambios en la documentacion"
|
23
|
-
},
|
24
|
-
{
|
25
|
-
"title": "Feature",
|
26
|
-
"value": "feature",
|
27
|
-
"description": "Nuevas funcionalidades"
|
28
|
-
}
|
29
|
-
]
|
8
|
+
"values": "labels"
|
9
|
+
},
|
10
|
+
"milestone": {
|
11
|
+
"type": "select",
|
12
|
+
"values": "milestones"
|
30
13
|
},
|
31
14
|
"body": { "required": false }
|
32
15
|
},
|
@@ -35,7 +18,7 @@
|
|
35
18
|
{
|
36
19
|
"name": "Crear un issue nuevo",
|
37
20
|
"function": "createIssue",
|
38
|
-
"arguments": ["${title}", "${label}", "${body}"]
|
21
|
+
"arguments": ["${title}", "${label}", "${body}", "${milestone}"]
|
39
22
|
}
|
40
23
|
]
|
41
24
|
}
|
@@ -1,11 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"name": "list",
|
3
3
|
"guards": ["isGitApi"],
|
4
|
+
"arguments": ["filter", "template"],
|
4
5
|
"description": "Comando para ver en detalle el requerimiento",
|
5
6
|
"steps": [
|
6
7
|
{
|
7
8
|
"name": "Ver los issues del Backlog",
|
8
|
-
"function": "listIssues"
|
9
|
+
"function": "listIssues",
|
10
|
+
"arguments": ["${filter}", "${template}"]
|
9
11
|
}
|
10
12
|
]
|
11
13
|
}
|
@@ -8,6 +8,7 @@
|
|
8
8
|
"steps": [
|
9
9
|
{ "name": "Paquetiza", "subtask": "pack" },
|
10
10
|
{ "name": "Actualiza la version", "function": "storeConfig", "arguments": ["version", "${newVersion}"] },
|
11
|
-
{ "name": "Publica", "command": "yarn publish ", "arguments": {"--new-version": "${newVersion}"} }
|
11
|
+
{ "name": "Publica", "command": "yarn publish ", "arguments": {"--new-version": "${newVersion}"} },
|
12
|
+
{ "name": "Salida para el Changelog.md", "task": "list", "arguments": {"filter": "milestone", "template": "changelog", "milestone": "${newVersion}"} }
|
12
13
|
]
|
13
14
|
}
|
package/lib/auto.js
CHANGED
@@ -39,10 +39,10 @@ export default function main() {
|
|
39
39
|
const taskName = yield askForTaskName(config.taskName, tasks);
|
40
40
|
if (taskName) {
|
41
41
|
const task = tasks[taskName];
|
42
|
-
|
42
|
+
context.options = config.arguments && task.arguments ? Object.assign(Object.assign({}, config.options), createObject(task.arguments, config.arguments)) : config.options;
|
43
43
|
// Valida los json de task y subtask
|
44
44
|
if (validateTask(task)) {
|
45
|
-
yield taskCommand[config.command](task, options);
|
45
|
+
yield taskCommand[config.command](task, context.options);
|
46
46
|
}
|
47
47
|
else {
|
48
48
|
logError('Verifique que los json de task y subtask esten validos');
|
@@ -50,7 +50,7 @@ export default function main() {
|
|
50
50
|
}
|
51
51
|
}
|
52
52
|
else {
|
53
|
-
yield proxyCommand[config.command]();
|
53
|
+
yield proxyCommand[config.command](config.taskName, config.options);
|
54
54
|
}
|
55
55
|
}
|
56
56
|
catch (error) {
|
package/lib/helpers/context.d.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import prompts from "prompts";
|
1
2
|
import type { PromptChoices } from "../types/helpers/context.js";
|
2
3
|
import type { IProcessHeader, Processes, AnyValue, IProcessInfo, ObjectRecord, IObjectRecord } from "../types/auto.js";
|
3
4
|
import type { TaskArguments, TaskArgument, StepArguments } from "../types/helpers/tasks.js";
|
@@ -6,6 +7,11 @@ export declare enum GitServices {
|
|
6
7
|
GitLab = "gitlab",
|
7
8
|
None = "none"
|
8
9
|
}
|
10
|
+
export declare enum ListFilters {
|
11
|
+
Mios = "mios",
|
12
|
+
PorMilestone = "milestone",
|
13
|
+
PorLabel = "label"
|
14
|
+
}
|
9
15
|
export declare enum ProjectServices {
|
10
16
|
GitHub = "github",
|
11
17
|
GitLab = "gitlab",
|
@@ -20,6 +26,7 @@ declare class Context implements IObjectRecord {
|
|
20
26
|
isGitApi: boolean;
|
21
27
|
gitApi: IGitApi | undefined;
|
22
28
|
version: string | undefined;
|
29
|
+
options: Record<string, AnyValue>;
|
23
30
|
projectServices: ProjectServices;
|
24
31
|
isProjectApi: boolean;
|
25
32
|
projectApi: IProjectApi | undefined;
|
@@ -49,7 +56,13 @@ declare class Context implements IObjectRecord {
|
|
49
56
|
repositoryRepo: string | undefined;
|
50
57
|
projectId: string | undefined;
|
51
58
|
backlogColumn: string;
|
59
|
+
listFilter: ListFilters;
|
60
|
+
listTemplate: string;
|
52
61
|
constructor();
|
62
|
+
labels(): Promise<prompts.Choice[]>;
|
63
|
+
listFilters(): prompts.Choice[];
|
64
|
+
milestoneNumbers(): Promise<prompts.Choice[]>;
|
65
|
+
milestones(): Promise<prompts.Choice[]>;
|
53
66
|
loadProjectApi(): void;
|
54
67
|
loadGitApi(): void;
|
55
68
|
loadPackage(): void;
|
@@ -85,7 +98,7 @@ declare class Context implements IObjectRecord {
|
|
85
98
|
get process(): string | undefined;
|
86
99
|
askForprocess(): Promise<any>;
|
87
100
|
askFornewIssueType(): Promise<any>;
|
88
|
-
convertToArrayOfInputs(inputs: TaskArguments): TaskArgument[]
|
101
|
+
convertToArrayOfInputs(inputs: TaskArguments): Promise<TaskArgument[]>;
|
89
102
|
askForExit(): Promise<void>;
|
90
103
|
mergeArgs(args: StepArguments): StepArguments;
|
91
104
|
askForArguments(inputs: TaskArguments): Promise<void>;
|
package/lib/helpers/context.js
CHANGED
@@ -22,6 +22,12 @@ export var GitServices;
|
|
22
22
|
GitServices["GitLab"] = "gitlab";
|
23
23
|
GitServices["None"] = "none";
|
24
24
|
})(GitServices || (GitServices = {}));
|
25
|
+
export var ListFilters;
|
26
|
+
(function (ListFilters) {
|
27
|
+
ListFilters["Mios"] = "mios";
|
28
|
+
ListFilters["PorMilestone"] = "milestone";
|
29
|
+
ListFilters["PorLabel"] = "label";
|
30
|
+
})(ListFilters || (ListFilters = {}));
|
25
31
|
export var ProjectServices;
|
26
32
|
(function (ProjectServices) {
|
27
33
|
ProjectServices["GitHub"] = "github";
|
@@ -37,6 +43,7 @@ class Context {
|
|
37
43
|
this.modelTemplates = 'modelA'; // Default Model de templates
|
38
44
|
this.gitServices = GitServices.None;
|
39
45
|
this.isGitApi = false;
|
46
|
+
this.options = {};
|
40
47
|
this.projectServices = ProjectServices.None;
|
41
48
|
this.isProjectApi = false;
|
42
49
|
this.sfInstalled = true;
|
@@ -47,9 +54,49 @@ class Context {
|
|
47
54
|
// Ultima salida del shell
|
48
55
|
this.salida = '';
|
49
56
|
this.backlogColumn = 'Todo';
|
57
|
+
//Templates especiales
|
58
|
+
this.listFilter = ListFilters.Mios;
|
59
|
+
this.listTemplate = 'openIssues';
|
50
60
|
this.loadConfig();
|
51
61
|
this.loadPackage();
|
52
62
|
}
|
63
|
+
labels() {
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
65
|
+
var _a;
|
66
|
+
const choices = [{ value: '', title: 'Ninguno' }];
|
67
|
+
const labels = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getLabels());
|
68
|
+
if (labels) {
|
69
|
+
labels.forEach(label => choices.push({ value: label.name, title: label.name }));
|
70
|
+
}
|
71
|
+
return choices;
|
72
|
+
});
|
73
|
+
}
|
74
|
+
listFilters() {
|
75
|
+
const filters = [{ title: 'Solo mios abiertos', value: ListFilters.Mios, description: 'Busca los issues donde este asignado y esten en state Open' }, { title: 'Por Milestone', value: ListFilters.PorMilestone, description: 'Busca los issues de un deterinado milestone' }, { title: 'Por Label', value: ListFilters.PorLabel, description: 'Busca los issues de un deterinado label' }];
|
76
|
+
return filters;
|
77
|
+
}
|
78
|
+
milestoneNumbers() {
|
79
|
+
return __awaiter(this, void 0, void 0, function* () {
|
80
|
+
var _a;
|
81
|
+
const choices = [{ value: '', title: 'Ninguno' }];
|
82
|
+
const milestones = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getMilestones());
|
83
|
+
if (milestones) {
|
84
|
+
milestones.forEach(milestone => choices.push({ value: milestone.number, title: milestone.title }));
|
85
|
+
}
|
86
|
+
return choices;
|
87
|
+
});
|
88
|
+
}
|
89
|
+
milestones() {
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
91
|
+
var _a;
|
92
|
+
const choices = [{ value: '', title: 'Ninguno' }];
|
93
|
+
const milestones = yield ((_a = this.gitApi) === null || _a === void 0 ? void 0 : _a.getMilestones());
|
94
|
+
if (milestones) {
|
95
|
+
milestones.forEach(milestone => choices.push({ value: milestone.id, title: milestone.title }));
|
96
|
+
}
|
97
|
+
return choices;
|
98
|
+
});
|
99
|
+
}
|
53
100
|
loadProjectApi() {
|
54
101
|
if (!this.isProjectApi) {
|
55
102
|
if (this.projectServices == ProjectServices.GitHub && process.env.GITHUB_TOKEN) {
|
@@ -369,7 +416,7 @@ class Context {
|
|
369
416
|
askForprocess() {
|
370
417
|
return __awaiter(this, void 0, void 0, function* () {
|
371
418
|
if (this.projectApi && !this.issueTitle && this.issueNumber) {
|
372
|
-
const issue = yield this.projectApi.
|
419
|
+
const issue = yield this.projectApi.getIssue(this.issueNumber);
|
373
420
|
this.issueTitle = issue.title;
|
374
421
|
}
|
375
422
|
if (this.issueTitle) {
|
@@ -405,22 +452,29 @@ class Context {
|
|
405
452
|
});
|
406
453
|
}
|
407
454
|
convertToArrayOfInputs(inputs) {
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
455
|
+
return __awaiter(this, void 0, void 0, function* () {
|
456
|
+
let inputsArray = [];
|
457
|
+
if (Array.isArray(inputs)) {
|
458
|
+
// Si viene los args como ['name1', 'names] lo convierte a [{name: 'name1'}, {name: 'name2'}]
|
459
|
+
inputsArray = inputs.map(input => { return { name: input, type: 'text', message: `Por favor ingrese ${input}?` }; });
|
460
|
+
}
|
461
|
+
else {
|
462
|
+
// Si viene args como objeto { name1: {...}, name2: {...}} lo convierte a [{name: name1...}, {name: name2...}]
|
463
|
+
for (const key in inputs) {
|
464
|
+
if (typeof inputs[key].default == 'string') {
|
465
|
+
inputs[key].initial = this.merge(inputs[key].default);
|
466
|
+
}
|
467
|
+
if (typeof inputs[key].values == 'string' && typeof this[inputs[key].values] == 'function') {
|
468
|
+
const choices = yield this[inputs[key].values]();
|
469
|
+
if (Array.isArray(choices)) {
|
470
|
+
inputs[key].choices = choices;
|
471
|
+
}
|
472
|
+
}
|
473
|
+
inputsArray.push(Object.assign({ name: key, type: 'text', message: `Por favor ingrese ${key}?` }, inputs[key]));
|
419
474
|
}
|
420
|
-
inputsArray.push(Object.assign({ name: key, type: 'text', initial, message: `Por favor ingrese ${key}?` }, inputs[key]));
|
421
475
|
}
|
422
|
-
|
423
|
-
|
476
|
+
return inputsArray;
|
477
|
+
});
|
424
478
|
}
|
425
479
|
askForExit() {
|
426
480
|
return __awaiter(this, void 0, void 0, function* () {
|
@@ -459,7 +513,7 @@ class Context {
|
|
459
513
|
askForArguments(inputs) {
|
460
514
|
return __awaiter(this, void 0, void 0, function* () {
|
461
515
|
// unifica los dos tipos de inputs (array y objeto) en un array de inputs
|
462
|
-
const inputsArray = this.convertToArrayOfInputs(inputs);
|
516
|
+
const inputsArray = yield this.convertToArrayOfInputs(inputs);
|
463
517
|
for (const input of inputsArray) {
|
464
518
|
const hasValue = yield this.get(input.name);
|
465
519
|
if (!hasValue) {
|
@@ -10,6 +10,8 @@ export declare class GitHubApi implements IGitApi {
|
|
10
10
|
login: string;
|
11
11
|
id: number;
|
12
12
|
}>;
|
13
|
+
getLabels(): Promise<ILabel[]>;
|
14
|
+
getMilestones(): Promise<IMilestone[]>;
|
13
15
|
getRepository(label?: string): Promise<{
|
14
16
|
id: string;
|
15
17
|
label?: {
|
@@ -29,39 +31,6 @@ export declare class GitHubApi implements IGitApi {
|
|
29
31
|
}>;
|
30
32
|
createPullRequest(branchName: string, title: string, body: string): Promise<boolean>;
|
31
33
|
assignBranchToIssue(issueNumber: string, branchName: string, commitSha: string): Promise<boolean>;
|
32
|
-
getIssue(issueNumber: string): Promise<{
|
33
|
-
id: string;
|
34
|
-
title: string;
|
35
|
-
labels: {
|
36
|
-
nodes: {
|
37
|
-
name: string;
|
38
|
-
color: string;
|
39
|
-
}[];
|
40
|
-
};
|
41
|
-
projectItems: {
|
42
|
-
nodes: {
|
43
|
-
id: string;
|
44
|
-
project: {
|
45
|
-
id: string;
|
46
|
-
};
|
47
|
-
fieldValueByName: {
|
48
|
-
name: string;
|
49
|
-
id: string;
|
50
|
-
field: {
|
51
|
-
id: string;
|
52
|
-
};
|
53
|
-
};
|
54
|
-
}[];
|
55
|
-
};
|
56
|
-
linkedBranches: {
|
57
|
-
nodes: {
|
58
|
-
ref: {
|
59
|
-
id: string;
|
60
|
-
name: string;
|
61
|
-
};
|
62
|
-
}[];
|
63
|
-
};
|
64
|
-
}>;
|
65
34
|
getCommit(commitSha: string): Promise<{
|
66
35
|
id: string;
|
67
36
|
oid: string;
|
@@ -31,6 +31,45 @@ export class GitHubApi {
|
|
31
31
|
return viewer;
|
32
32
|
});
|
33
33
|
}
|
34
|
+
getLabels() {
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
36
|
+
const query = `
|
37
|
+
query getRepo($owner:String!, $repo: String! ) {
|
38
|
+
repository(owner: $owner, name: $repo) {
|
39
|
+
labels(last: 10, orderBy: { field: CREATED_AT, direction: DESC}) {
|
40
|
+
nodes{
|
41
|
+
id
|
42
|
+
name
|
43
|
+
color
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
`;
|
49
|
+
const { repository } = yield this.graphqlAuth(query, this.repoVar);
|
50
|
+
return repository.labels.nodes;
|
51
|
+
});
|
52
|
+
}
|
53
|
+
getMilestones() {
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
55
|
+
const query = `
|
56
|
+
query getRepo($owner:String!, $repo: String! ) {
|
57
|
+
repository(owner: $owner, name: $repo) {
|
58
|
+
milestones(last: 10, states: OPEN, orderBy: { field: CREATED_AT, direction: DESC} ) {
|
59
|
+
nodes{
|
60
|
+
id
|
61
|
+
number
|
62
|
+
title
|
63
|
+
dueOn
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
`;
|
69
|
+
const { repository } = yield this.graphqlAuth(query, this.repoVar);
|
70
|
+
return repository.milestones.nodes;
|
71
|
+
});
|
72
|
+
}
|
34
73
|
getRepository(label) {
|
35
74
|
return __awaiter(this, void 0, void 0, function* () {
|
36
75
|
const query = `
|
@@ -97,7 +136,17 @@ export class GitHubApi {
|
|
97
136
|
assignBranchToIssue(issueNumber, branchName, commitSha) {
|
98
137
|
return __awaiter(this, void 0, void 0, function* () {
|
99
138
|
var _a;
|
100
|
-
const
|
139
|
+
const query = `
|
140
|
+
query getIssue($owner:String!, $repo: String!, $issueNumber: Int!) {
|
141
|
+
repository(owner: $owner, name: $repo) {
|
142
|
+
issue(number: $issueNumber) {
|
143
|
+
id
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
147
|
+
`;
|
148
|
+
const { repository } = yield this.graphqlAuth(query, Object.assign({ issueNumber: Number.parseInt(issueNumber) }, this.repoVar));
|
149
|
+
const issue = repository.issue;
|
101
150
|
const commit = yield this.getCommit(commitSha);
|
102
151
|
const mutation = `
|
103
152
|
mutation createLinkedBranch( $issueId: ID!, $oid: GitObjectID!, $branchName: String!) {
|
@@ -116,55 +165,6 @@ export class GitHubApi {
|
|
116
165
|
return ((_a = createLinkedBranch === null || createLinkedBranch === void 0 ? void 0 : createLinkedBranch.issue) === null || _a === void 0 ? void 0 : _a.id) ? true : false;
|
117
166
|
});
|
118
167
|
}
|
119
|
-
getIssue(issueNumber) {
|
120
|
-
return __awaiter(this, void 0, void 0, function* () {
|
121
|
-
const query = `
|
122
|
-
query getIssue($owner:String!, $repo: String!, $issueNumber: Int!) {
|
123
|
-
repository(owner: $owner, name: $repo) {
|
124
|
-
issue(number: $issueNumber) {
|
125
|
-
title
|
126
|
-
id
|
127
|
-
labels(first:3, orderBy: { field: CREATED_AT, direction: DESC}) {
|
128
|
-
nodes {
|
129
|
-
color
|
130
|
-
name
|
131
|
-
}
|
132
|
-
}
|
133
|
-
projectItems(last: 1) {
|
134
|
-
nodes{
|
135
|
-
id,
|
136
|
-
project {
|
137
|
-
id
|
138
|
-
}
|
139
|
-
fieldValueByName(name: "Status"){
|
140
|
-
... on ProjectV2ItemFieldSingleSelectValue {
|
141
|
-
name
|
142
|
-
id
|
143
|
-
field {
|
144
|
-
... on ProjectV2SingleSelectField {
|
145
|
-
id
|
146
|
-
}
|
147
|
-
}
|
148
|
-
}
|
149
|
-
}
|
150
|
-
}
|
151
|
-
}
|
152
|
-
linkedBranches(last:1){
|
153
|
-
nodes {
|
154
|
-
ref {
|
155
|
-
id
|
156
|
-
name
|
157
|
-
}
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
}
|
163
|
-
`;
|
164
|
-
const { repository } = yield this.graphqlAuth(query, Object.assign({ issueNumber: Number.parseInt(issueNumber) }, this.repoVar));
|
165
|
-
return repository.issue;
|
166
|
-
});
|
167
|
-
}
|
168
168
|
getCommit(commitSha) {
|
169
169
|
return __awaiter(this, void 0, void 0, function* () {
|
170
170
|
const query = `
|
@@ -3,15 +3,47 @@ export declare class GitHubProjectApi extends GitHubApi implements IProjectApi {
|
|
3
3
|
projectNumber: number;
|
4
4
|
constructor(token: string, owner: string, repo: string, projectNumber: number);
|
5
5
|
getColumnValueMap(): Promise<Record<string, string>>;
|
6
|
-
createIssue(title: string, state?: string, label?: string, body?: string,
|
6
|
+
createIssue(title: string, state?: string, label?: string, body?: string, milestoneId?: string): Promise<number>;
|
7
7
|
getIssueState(issueNumber: string): Promise<string>;
|
8
8
|
getIssueName(title: string): string;
|
9
|
-
|
10
|
-
|
9
|
+
_getIssue(issueNumber: string): Promise<{
|
10
|
+
number: number;
|
11
11
|
id: string;
|
12
|
+
body: string;
|
13
|
+
url: string;
|
12
14
|
title: string;
|
13
|
-
|
14
|
-
|
15
|
+
labels: {
|
16
|
+
nodes: {
|
17
|
+
name: string;
|
18
|
+
color: string;
|
19
|
+
}[];
|
20
|
+
};
|
21
|
+
projectItems: {
|
22
|
+
nodes: {
|
23
|
+
id: string;
|
24
|
+
project: {
|
25
|
+
id: string;
|
26
|
+
};
|
27
|
+
fieldValueByName: {
|
28
|
+
name: string;
|
29
|
+
id: string;
|
30
|
+
field: {
|
31
|
+
id: string;
|
32
|
+
};
|
33
|
+
};
|
34
|
+
}[];
|
35
|
+
};
|
36
|
+
linkedBranches: {
|
37
|
+
nodes: {
|
38
|
+
ref: {
|
39
|
+
id: string;
|
40
|
+
name: string;
|
41
|
+
};
|
42
|
+
}[];
|
43
|
+
};
|
44
|
+
}>;
|
45
|
+
getIssue(issueNumber: string): Promise<IIssueObject>;
|
46
|
+
getIssues(): Promise<{
|
15
47
|
id: string;
|
16
48
|
title: string;
|
17
49
|
}[]>;
|
@@ -42,7 +42,7 @@ export class GitHubProjectApi extends GitHubApi {
|
|
42
42
|
return mapValues;
|
43
43
|
});
|
44
44
|
}
|
45
|
-
createIssue(title, state, label, body,
|
45
|
+
createIssue(title, state, label, body, milestoneId) {
|
46
46
|
return __awaiter(this, void 0, void 0, function* () {
|
47
47
|
var _a;
|
48
48
|
const user = yield this.getUser();
|
@@ -51,15 +51,15 @@ export class GitHubProjectApi extends GitHubApi {
|
|
51
51
|
const labelId = (_a = repository.label) === null || _a === void 0 ? void 0 : _a.id;
|
52
52
|
const projectId = repository.projectV2.id;
|
53
53
|
const mutationIssue = `
|
54
|
-
mutation createIssue($repositoryId: ID!, $assignId: ID!, $title: String!, $body: String, ${labelId ? '$labelId: ID!' : ''}
|
54
|
+
mutation createIssue($repositoryId: ID!, $assignId: ID!, $title: String!, $body: String, $milestoneId: ID ${labelId ? ', $labelId: ID!' : ''} ) {
|
55
55
|
createIssue(
|
56
56
|
input: {
|
57
57
|
repositoryId: $repositoryId,
|
58
58
|
assigneeIds: [$assignId],
|
59
|
-
${labelId ? 'labelIds: [$labelId],' : ''}
|
60
59
|
title: $title,
|
61
60
|
milestoneId: $milestoneId,
|
62
61
|
body: $body
|
62
|
+
${labelId ? ',labelIds: [$labelId]' : ''}
|
63
63
|
}
|
64
64
|
) {
|
65
65
|
issue {
|
@@ -68,7 +68,7 @@ export class GitHubProjectApi extends GitHubApi {
|
|
68
68
|
}
|
69
69
|
}
|
70
70
|
}`;
|
71
|
-
const { createIssue } = yield this.graphqlAuth(mutationIssue, { labelId, body, assignId: user.id, projectId, repositoryId, title, label: label ? [label] : null });
|
71
|
+
const { createIssue } = yield this.graphqlAuth(mutationIssue, { labelId, body, assignId: user.id, projectId, repositoryId, title, milestoneId: milestoneId ? milestoneId : null, label: label ? [label] : null });
|
72
72
|
const issue = createIssue.issue;
|
73
73
|
if (!state || !issue.number) {
|
74
74
|
return issue.number;
|
@@ -117,17 +117,69 @@ export class GitHubProjectApi extends GitHubApi {
|
|
117
117
|
getIssueState(issueNumber) {
|
118
118
|
return __awaiter(this, void 0, void 0, function* () {
|
119
119
|
var _a, _b, _c;
|
120
|
-
const issue = yield this.
|
120
|
+
const issue = yield this._getIssue(issueNumber);
|
121
121
|
return (_c = (_b = (_a = issue.projectItems) === null || _a === void 0 ? void 0 : _a.nodes[0]) === null || _b === void 0 ? void 0 : _b.fieldValueByName) === null || _c === void 0 ? void 0 : _c.name;
|
122
122
|
});
|
123
123
|
}
|
124
124
|
getIssueName(title) {
|
125
125
|
return title.toLowerCase().replaceAll(' ', '-');
|
126
126
|
}
|
127
|
-
|
127
|
+
_getIssue(issueNumber) {
|
128
128
|
return __awaiter(this, void 0, void 0, function* () {
|
129
|
-
const
|
130
|
-
|
129
|
+
const query = `
|
130
|
+
query getIssue($owner:String!, $repo: String!, $issueNumber: Int!) {
|
131
|
+
repository(owner: $owner, name: $repo) {
|
132
|
+
issue(number: $issueNumber) {
|
133
|
+
title
|
134
|
+
number,
|
135
|
+
id
|
136
|
+
url
|
137
|
+
body
|
138
|
+
labels(first:3, orderBy: { field: CREATED_AT, direction: DESC}) {
|
139
|
+
nodes {
|
140
|
+
color
|
141
|
+
name
|
142
|
+
}
|
143
|
+
}
|
144
|
+
projectItems(last: 1) {
|
145
|
+
nodes{
|
146
|
+
id,
|
147
|
+
project {
|
148
|
+
id
|
149
|
+
}
|
150
|
+
fieldValueByName(name: "Status"){
|
151
|
+
... on ProjectV2ItemFieldSingleSelectValue {
|
152
|
+
name
|
153
|
+
id
|
154
|
+
field {
|
155
|
+
... on ProjectV2SingleSelectField {
|
156
|
+
id
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
linkedBranches(last:1){
|
164
|
+
nodes {
|
165
|
+
ref {
|
166
|
+
id
|
167
|
+
name
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
`;
|
175
|
+
const { repository } = yield this.graphqlAuth(query, Object.assign({ issueNumber: Number.parseInt(issueNumber) }, this.repoVar));
|
176
|
+
return repository.issue;
|
177
|
+
});
|
178
|
+
}
|
179
|
+
getIssue(issueNumber) {
|
180
|
+
return __awaiter(this, void 0, void 0, function* () {
|
181
|
+
const issue = yield this._getIssue(issueNumber);
|
182
|
+
const issueObject = { number: issue.number, title: issue.title, id: issue.id, url: issue.url, body: issue.body };
|
131
183
|
issueObject.name = this.getIssueName(issue.title);
|
132
184
|
if (issue.linkedBranches.nodes.length > 0) {
|
133
185
|
issueObject.branch = issue.linkedBranches.nodes[0].ref.name;
|
@@ -149,11 +201,6 @@ export class GitHubProjectApi extends GitHubApi {
|
|
149
201
|
return yield this.getIssuesWithFilter(`{ states: OPEN }`);
|
150
202
|
});
|
151
203
|
}
|
152
|
-
getIssuesByMilestone(milestone) {
|
153
|
-
return __awaiter(this, void 0, void 0, function* () {
|
154
|
-
return yield this.getIssuesWithFilter(`{ milestone: ${milestone} }`);
|
155
|
-
});
|
156
|
-
}
|
157
204
|
getIssuesWithFilter(filterBy) {
|
158
205
|
return __awaiter(this, void 0, void 0, function* () {
|
159
206
|
const query = `
|
@@ -161,7 +208,26 @@ export class GitHubProjectApi extends GitHubApi {
|
|
161
208
|
repository(owner: $owner, name: $repo) {
|
162
209
|
issues(last: 10, filterBy: ${filterBy} ) {
|
163
210
|
nodes {
|
211
|
+
number
|
164
212
|
title
|
213
|
+
body
|
214
|
+
state
|
215
|
+
url
|
216
|
+
milestone {
|
217
|
+
dueOn
|
218
|
+
title
|
219
|
+
}
|
220
|
+
labels ( last: 3, orderBy: { field: CREATED_AT, direction: DESC} ) {
|
221
|
+
nodes {
|
222
|
+
color
|
223
|
+
name
|
224
|
+
}
|
225
|
+
}
|
226
|
+
assignees ( last: 3 ) {
|
227
|
+
nodes {
|
228
|
+
login
|
229
|
+
}
|
230
|
+
}
|
165
231
|
id
|
166
232
|
}
|
167
233
|
}
|
@@ -174,7 +240,7 @@ export class GitHubProjectApi extends GitHubApi {
|
|
174
240
|
}
|
175
241
|
moveIssue(issueNumber, state) {
|
176
242
|
return __awaiter(this, void 0, void 0, function* () {
|
177
|
-
const issue = yield this.
|
243
|
+
const issue = yield this._getIssue(issueNumber);
|
178
244
|
const itemId = issue.projectItems.nodes[0].id;
|
179
245
|
const projectId = issue.projectItems.nodes[0].project.id;
|
180
246
|
const fieldId = issue.projectItems.nodes[0].fieldValueByName.field.id;
|
@@ -202,7 +268,7 @@ export class GitHubProjectApi extends GitHubApi {
|
|
202
268
|
assignIssueToMe(issueNumber) {
|
203
269
|
return __awaiter(this, void 0, void 0, function* () {
|
204
270
|
const user = yield this.getUser();
|
205
|
-
const issue = yield this.
|
271
|
+
const issue = yield this._getIssue(issueNumber);
|
206
272
|
const mutation = `
|
207
273
|
mutation assignUser( $issueId: ID!, $userId: ID!) {
|
208
274
|
addAssigneesToAssignable(input: {
|
@@ -8,9 +8,11 @@ export declare class GitLabApi implements IGitApi, IProjectApi {
|
|
8
8
|
projectNumber: number | undefined;
|
9
9
|
graphqlAuth: GraphQLClient;
|
10
10
|
constructor(token: string, owner: string, repo: string, projectNumber?: number);
|
11
|
-
|
11
|
+
getLabels(): Promise<never[]>;
|
12
|
+
getMilestones(): Promise<never[]>;
|
13
|
+
getIssue(issueNumber: string): Promise<{}>;
|
12
14
|
getIssues(): Promise<never[]>;
|
13
|
-
|
15
|
+
getIssuesWithFilter(filter: string): Promise<never[]>;
|
14
16
|
createIssue(title: string, state?: string, label?: string, body?: string, milestone?: string): Promise<number>;
|
15
17
|
moveIssue(issueNumber: string, state: string): Promise<boolean>;
|
16
18
|
assignIssueToMe(issueNumber: string): Promise<boolean>;
|
@@ -16,7 +16,17 @@ export class GitLabApi {
|
|
16
16
|
this.projectNumber = projectNumber;
|
17
17
|
this.graphqlAuth.setHeaders({ authorization: `Bearer ${token}` });
|
18
18
|
}
|
19
|
-
|
19
|
+
getLabels() {
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
21
|
+
return [];
|
22
|
+
});
|
23
|
+
}
|
24
|
+
getMilestones() {
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
26
|
+
return [];
|
27
|
+
});
|
28
|
+
}
|
29
|
+
getIssue(issueNumber) {
|
20
30
|
return __awaiter(this, void 0, void 0, function* () {
|
21
31
|
console.log(issueNumber);
|
22
32
|
return {};
|
@@ -27,7 +37,7 @@ export class GitLabApi {
|
|
27
37
|
return [];
|
28
38
|
});
|
29
39
|
}
|
30
|
-
|
40
|
+
getIssuesWithFilter(filter) {
|
31
41
|
return __awaiter(this, void 0, void 0, function* () {
|
32
42
|
return [];
|
33
43
|
});
|
@@ -8,13 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
8
8
|
});
|
9
9
|
};
|
10
10
|
import { execSync } from "child_process";
|
11
|
-
import context from "./context.js";
|
11
|
+
import context, { ListFilters } from "./context.js";
|
12
12
|
import { logError, logInfo } from "./color.js";
|
13
13
|
import metadata from './metadata.js';
|
14
14
|
import prompts from "prompts";
|
15
15
|
import templateGenerator from "./template.js";
|
16
|
-
import {
|
17
|
-
import { storeConfig, TEMPLATE_MODEL_FOLDER } from "./util.js";
|
16
|
+
import { filterBash, getFiles, storeConfig, TEMPLATE_MODEL_FOLDER, valuesToChoices } from "./util.js";
|
18
17
|
function generateTemplate(templateFolder, templateExtension, template, context) {
|
19
18
|
if (!template || !templateFolder || !templateExtension) {
|
20
19
|
return;
|
@@ -238,7 +237,7 @@ export const taskFunctions = {
|
|
238
237
|
return true;
|
239
238
|
},
|
240
239
|
storeConfig(variable, value) {
|
241
|
-
storeConfig(variable
|
240
|
+
storeConfig({ [variable]: value });
|
242
241
|
return true;
|
243
242
|
},
|
244
243
|
docProcess() {
|
@@ -334,12 +333,12 @@ export const taskFunctions = {
|
|
334
333
|
console.log('Not implemented');
|
335
334
|
return false;
|
336
335
|
},
|
337
|
-
createIssue(title, label, body) {
|
336
|
+
createIssue(title, label, body, milestone) {
|
338
337
|
return __awaiter(this, void 0, void 0, function* () {
|
339
338
|
if (context.projectApi === undefined) {
|
340
339
|
return false;
|
341
340
|
}
|
342
|
-
const issueNumber = yield context.projectApi.createIssue(title, context.backlogColumn, label, body);
|
341
|
+
const issueNumber = yield context.projectApi.createIssue(title, context.backlogColumn, label, body, milestone);
|
343
342
|
if (issueNumber) {
|
344
343
|
console.log(`Se creo el issue ${issueNumber}`);
|
345
344
|
return true;
|
@@ -359,7 +358,7 @@ export const taskFunctions = {
|
|
359
358
|
if (context.projectApi === undefined) {
|
360
359
|
return false;
|
361
360
|
}
|
362
|
-
const issue = yield context.projectApi.
|
361
|
+
const issue = yield context.projectApi.getIssue(issueNumber);
|
363
362
|
if (!issue.state) {
|
364
363
|
return false;
|
365
364
|
}
|
@@ -441,41 +440,108 @@ export const taskFunctions = {
|
|
441
440
|
return result;
|
442
441
|
});
|
443
442
|
},
|
444
|
-
viewIssue(
|
445
|
-
return __awaiter(this,
|
443
|
+
viewIssue(issueNumber_1) {
|
444
|
+
return __awaiter(this, arguments, void 0, function* (issueNumber, template = 'viewIssue') {
|
446
445
|
if (!context.projectApi) {
|
447
446
|
return false;
|
448
447
|
}
|
449
|
-
const result = yield context.projectApi.
|
450
|
-
|
451
|
-
|
452
|
-
console.log(result.branch);
|
453
|
-
}
|
454
|
-
else {
|
455
|
-
console.log('sin branch');
|
456
|
-
}
|
457
|
-
// Labels
|
458
|
-
if (result.labels) {
|
459
|
-
const labels = [];
|
460
|
-
for (const label of result.labels) {
|
461
|
-
labels.push(getColored(label, 'cyan'));
|
462
|
-
}
|
463
|
-
console.log(labels.join(' '));
|
464
|
-
}
|
465
|
-
// Body
|
466
|
-
if (result.body) {
|
467
|
-
console.log(result.body);
|
468
|
-
}
|
448
|
+
const result = yield context.projectApi.getIssue(issueNumber);
|
449
|
+
const rendered = generateTemplate(TEMPLATE_MODEL_FOLDER, 'bash', template, Object.assign({ issue: result }, context));
|
450
|
+
console.log(rendered);
|
469
451
|
return true;
|
470
452
|
});
|
471
453
|
},
|
472
|
-
listIssues() {
|
473
|
-
return __awaiter(this,
|
474
|
-
|
454
|
+
listIssues(listFilter, listTemplate) {
|
455
|
+
return __awaiter(this, void 0, void 0, function* () {
|
456
|
+
let filter = '{states: OPEN}';
|
457
|
+
const extension = '*';
|
458
|
+
if (!listFilter) {
|
459
|
+
listFilter = context.options.filter || context.listFilter;
|
460
|
+
}
|
461
|
+
if (!listTemplate) {
|
462
|
+
listTemplate = context.options.template || context.listTemplate;
|
463
|
+
}
|
464
|
+
if (!context.projectApi || !context.gitApi) {
|
475
465
|
return false;
|
476
466
|
}
|
477
|
-
|
478
|
-
|
467
|
+
if (!listFilter) {
|
468
|
+
const answer = yield prompts([
|
469
|
+
{
|
470
|
+
message: 'Elija un filtro, o bien lo puede dejar fijo en autoforce como listFilter',
|
471
|
+
name: 'filter',
|
472
|
+
type: 'select',
|
473
|
+
initial: 0,
|
474
|
+
choices: context.listFilters
|
475
|
+
}
|
476
|
+
]);
|
477
|
+
listFilter = answer.filter;
|
478
|
+
}
|
479
|
+
if (listFilter === ListFilters.PorMilestone) {
|
480
|
+
if (context.options.milestone) {
|
481
|
+
const milestoneFilter = (yield context.gitApi.getMilestones()).filter(milestone => milestone.title == context.options.milestone);
|
482
|
+
if (milestoneFilter.length === 0) {
|
483
|
+
return false;
|
484
|
+
}
|
485
|
+
filter = `{ milestoneNumber: "${milestoneFilter[0].number}"}`;
|
486
|
+
}
|
487
|
+
else {
|
488
|
+
const choices = (yield context.gitApi.getMilestones()).map(milestone => { return { value: milestone.number, title: milestone.title }; });
|
489
|
+
choices.push({ value: '', title: 'Issues sin Milestone' });
|
490
|
+
choices.push({ value: '*', title: 'Issues con Milestone' });
|
491
|
+
const answer = yield prompts([
|
492
|
+
{
|
493
|
+
message: 'Elija un milestone',
|
494
|
+
name: 'filterValue',
|
495
|
+
type: 'select',
|
496
|
+
initial: 0,
|
497
|
+
choices
|
498
|
+
}
|
499
|
+
]);
|
500
|
+
filter = `{ milestoneNumber: "${answer.filterValue}"}`;
|
501
|
+
if (answer.filterValue === undefined)
|
502
|
+
return false;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
if (listFilter === ListFilters.PorLabel) {
|
506
|
+
if (context.options.label) {
|
507
|
+
filter = `{labels: "${context.options.label}"}`;
|
508
|
+
}
|
509
|
+
else {
|
510
|
+
const labels = (yield context.gitApi.getLabels()).map(label => label.name);
|
511
|
+
const choices = valuesToChoices(labels);
|
512
|
+
const answer = yield prompts([
|
513
|
+
{
|
514
|
+
message: 'Elija un label',
|
515
|
+
name: 'filterValue',
|
516
|
+
type: 'select',
|
517
|
+
initial: 0,
|
518
|
+
choices
|
519
|
+
}
|
520
|
+
]);
|
521
|
+
if (answer.filterValue === undefined)
|
522
|
+
return false;
|
523
|
+
filter = `{labels: "${answer.filterValue}"}`;
|
524
|
+
}
|
525
|
+
}
|
526
|
+
if (!listTemplate) {
|
527
|
+
const files = getFiles(TEMPLATE_MODEL_FOLDER, filterBash).map(filename => filename.split(".")[0]);
|
528
|
+
const templates = valuesToChoices(files);
|
529
|
+
const answer = yield prompts([
|
530
|
+
{
|
531
|
+
message: 'Elija un template, o bien lo puede dejar en autoforce como listTemplate',
|
532
|
+
name: 'template',
|
533
|
+
type: 'select',
|
534
|
+
initial: 0,
|
535
|
+
choices: templates
|
536
|
+
}
|
537
|
+
]);
|
538
|
+
listTemplate = answer.template;
|
539
|
+
if (listTemplate === undefined)
|
540
|
+
return false;
|
541
|
+
}
|
542
|
+
const result = yield context.projectApi.getIssuesWithFilter(filter);
|
543
|
+
console.log(context.version);
|
544
|
+
const rendered = generateTemplate(TEMPLATE_MODEL_FOLDER, extension, listTemplate, { issues: result, context });
|
479
545
|
console.log(rendered);
|
480
546
|
return true;
|
481
547
|
});
|
@@ -486,7 +552,7 @@ export const taskFunctions = {
|
|
486
552
|
if (!context.projectApi) {
|
487
553
|
return false;
|
488
554
|
}
|
489
|
-
const issue = yield context.projectApi.
|
555
|
+
const issue = yield context.projectApi.getIssue(issueNumber);
|
490
556
|
// Setea el issueType segun el issue
|
491
557
|
try {
|
492
558
|
let newIssueType = 'feature';
|
package/lib/helpers/tasks.js
CHANGED
@@ -95,6 +95,10 @@ export function validateTask(task) {
|
|
95
95
|
const subtask = getTask(step.subtask, SUBTASKS_FOLDER);
|
96
96
|
validateStep = validateTask(subtask);
|
97
97
|
}
|
98
|
+
else if (typeof step.task === 'string') {
|
99
|
+
const subtask = getTask(step.task, TASKS_FOLDER);
|
100
|
+
validateStep = validateTask(subtask);
|
101
|
+
}
|
98
102
|
else {
|
99
103
|
console.log('Step no tiene command ni function ni subtask');
|
100
104
|
}
|
@@ -176,8 +180,8 @@ function runStep(step, tabs) {
|
|
176
180
|
else if (typeof step.function === 'string') {
|
177
181
|
return yield executeFunction(step);
|
178
182
|
}
|
179
|
-
else if (typeof step.subtask === 'string') {
|
180
|
-
const subtask = getTask(step.subtask, SUBTASKS_FOLDER);
|
183
|
+
else if (typeof step.subtask === 'string' || typeof step.task === 'string') {
|
184
|
+
const subtask = typeof step.subtask === 'string' ? getTask(step.subtask, SUBTASKS_FOLDER) : getTask(step.task, TASKS_FOLDER);
|
181
185
|
let stepContext = step.arguments ? context.mergeArgs(step.arguments) : {};
|
182
186
|
if (Array.isArray(stepContext)) {
|
183
187
|
stepContext = createObject(subtask.arguments, stepContext);
|
@@ -3,8 +3,9 @@ declare class TemplateEngine {
|
|
3
3
|
_rendered: string | undefined;
|
4
4
|
_extension: string;
|
5
5
|
_sourceFolder: string;
|
6
|
-
constructor(source: string, extension
|
6
|
+
constructor(source: string, extension?: string);
|
7
7
|
getTemplates(): string[];
|
8
|
+
getNameAndExtension(templateName: string): string[];
|
8
9
|
read(templateName: string): void;
|
9
10
|
render(context: object, options?: RuntimeOptions): void;
|
10
11
|
get rendered(): string | undefined;
|
package/lib/helpers/template.js
CHANGED
@@ -23,7 +23,7 @@ function openTemplate(sourceFolder, templateName, extension) {
|
|
23
23
|
return content;
|
24
24
|
}
|
25
25
|
class TemplateEngine {
|
26
|
-
constructor(source, extension) {
|
26
|
+
constructor(source, extension = '*') {
|
27
27
|
this._sourceFolder = source;
|
28
28
|
if (!fs.existsSync(this._sourceFolder)) {
|
29
29
|
throw new Error(`La carpeta source ${this._sourceFolder} no existe!`);
|
@@ -32,7 +32,7 @@ class TemplateEngine {
|
|
32
32
|
}
|
33
33
|
;
|
34
34
|
getTemplates() {
|
35
|
-
const filterThisExtension = (file) => file.endsWith(`.${this._extension}`);
|
35
|
+
const filterThisExtension = (file) => file.endsWith(`.${this._extension}`) || this._extension === '*';
|
36
36
|
const templates = [];
|
37
37
|
const files = getFiles(this._sourceFolder, filterThisExtension, true, ['dictionary']);
|
38
38
|
for (const filename of files) {
|
@@ -41,8 +41,25 @@ class TemplateEngine {
|
|
41
41
|
}
|
42
42
|
return templates;
|
43
43
|
}
|
44
|
+
getNameAndExtension(templateName) {
|
45
|
+
// Si viene la extension en el nombre la extrae
|
46
|
+
if (templateName.split(".").length > 1) {
|
47
|
+
return templateName.split(".");
|
48
|
+
}
|
49
|
+
// Si viene la extension * busca cual puede ser en el directorio
|
50
|
+
if (this._extension === '*' || this._extension === '') {
|
51
|
+
const fileNames = getFiles(this._sourceFolder, fileName => fileName.split(".")[0].endsWith(templateName));
|
52
|
+
if (fileNames.length > 0) {
|
53
|
+
return fileNames[0].split(".");
|
54
|
+
}
|
55
|
+
}
|
56
|
+
// Por defecto usa el templateName como nombre y la extension
|
57
|
+
return [templateName, this._extension];
|
58
|
+
}
|
44
59
|
read(templateName) {
|
45
|
-
|
60
|
+
// Por defecto usa el templateName como nombre y la extension
|
61
|
+
const [name, extension] = this.getNameAndExtension(templateName);
|
62
|
+
const rawTemplate = openTemplate(this._sourceFolder, name, extension);
|
46
63
|
this._template = Handlebars.compile(rawTemplate);
|
47
64
|
}
|
48
65
|
render(context, options = {}) {
|
package/lib/helpers/util.d.ts
CHANGED
@@ -8,6 +8,7 @@ export declare const WORKING_FOLDER: string;
|
|
8
8
|
export declare const filterJson: (fullPath: string) => boolean;
|
9
9
|
export declare const filterDirectory: (fullPath: string) => boolean;
|
10
10
|
export declare const filterFiles: (fullPath: string) => boolean;
|
11
|
+
export declare const filterBash: (fullPath: string) => boolean;
|
11
12
|
export declare const camelToText: (s: string) => string;
|
12
13
|
export declare const kebabToText: (s: string) => string;
|
13
14
|
export declare const snakeToText: (s: string) => string;
|
@@ -21,9 +22,9 @@ export declare function titlesToChoices(list: string[], titleToValue?: (title: s
|
|
21
22
|
}[];
|
22
23
|
export declare function getDataFromPackage(): Record<string, string>;
|
23
24
|
export declare function findChoicesPosition(choices: Choice[], value: string): number;
|
24
|
-
export declare function createConfigurationFile(): Promise<boolean>;
|
25
|
+
export declare function createConfigurationFile(taskName?: string): Promise<boolean>;
|
25
26
|
export declare function getConfig(variable: string, defaultValue: AnyValue): any;
|
26
|
-
export declare function storeConfig(
|
27
|
+
export declare function storeConfig(record: Record<string, AnyValue>): void;
|
27
28
|
export declare function sortByName(objA: {
|
28
29
|
Name: string;
|
29
30
|
}, objB: {
|
package/lib/helpers/util.js
CHANGED
@@ -21,6 +21,7 @@ export const WORKING_FOLDER = process.env.INIT_CWD || ".";
|
|
21
21
|
export const filterJson = (fullPath) => fullPath.endsWith(".json");
|
22
22
|
export const filterDirectory = (fullPath) => fs.lstatSync(fullPath).isDirectory();
|
23
23
|
export const filterFiles = (fullPath) => !fs.lstatSync(fullPath).isDirectory();
|
24
|
+
export const filterBash = (fullPath) => fullPath.endsWith(".bash");
|
24
25
|
export const camelToText = (s) => s.replace(/[A-Z]/g, x => ' ' + x);
|
25
26
|
export const kebabToText = (s) => s.replace(/-./g, x => ' ' + x[1].toUpperCase());
|
26
27
|
export const snakeToText = (s) => s.replace(/_./g, x => ' ' + x[1].toUpperCase());
|
@@ -73,10 +74,45 @@ export function findChoicesPosition(choices, value) {
|
|
73
74
|
const index = choices.findIndex(choice => choice.value === value);
|
74
75
|
return index === -1 ? 0 : index;
|
75
76
|
}
|
76
|
-
|
77
|
+
function getTaskConfig(config) {
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
79
|
+
// TODO: Ver si esto se mueve a un config list
|
80
|
+
// List Command settings
|
81
|
+
const filters = context.listFilters();
|
82
|
+
const listFilter = yield prompts([
|
83
|
+
{
|
84
|
+
message: 'Elija un filtro, o bien lo puede dejar fijo en autoforce como listFilter',
|
85
|
+
name: 'filter',
|
86
|
+
type: 'select',
|
87
|
+
initial: findChoicesPosition(filters, config.listFilter),
|
88
|
+
choices: filters
|
89
|
+
}
|
90
|
+
]);
|
91
|
+
if (listFilter.filter === undefined)
|
92
|
+
return;
|
93
|
+
config.listFilter = listFilter.filter;
|
94
|
+
const files = getFiles(`${TEMPLATES_FOLDER}/${config.modelTemplates}`, filterBash).map(filename => filename.split(".")[0]);
|
95
|
+
if (files.length > 0) {
|
96
|
+
const templates = valuesToChoices(files);
|
97
|
+
const template = yield prompts([
|
98
|
+
{
|
99
|
+
message: 'Elija un template, o bien lo puede dejar en autoforce como listTemplate',
|
100
|
+
name: 'template',
|
101
|
+
type: 'select',
|
102
|
+
initial: findChoicesPosition(templates, config.listTemplate),
|
103
|
+
choices: templates
|
104
|
+
}
|
105
|
+
]);
|
106
|
+
if (template.template === undefined)
|
107
|
+
return;
|
108
|
+
config.listTemplate = template.template;
|
109
|
+
}
|
110
|
+
return config;
|
111
|
+
});
|
112
|
+
}
|
113
|
+
function getBaseConfig(config) {
|
77
114
|
return __awaiter(this, void 0, void 0, function* () {
|
78
115
|
// Todo: Chequear el repoOwner y repo
|
79
|
-
const config = { backlogColumn: context.backlogColumn, model: context.model, modelTemplates: context.modelTemplates, gitServices: context.gitServices, projectServices: context.projectServices, projectId: context.projectId };
|
80
116
|
const gitChoices = [{ title: 'Github', value: GitServices.GitHub }, { title: 'Gitlab', value: GitServices.GitLab }];
|
81
117
|
// Preguntar por GitHub o GitLab
|
82
118
|
const gitServices = yield prompts([{
|
@@ -87,7 +123,7 @@ export function createConfigurationFile() {
|
|
87
123
|
choices: gitChoices
|
88
124
|
}]);
|
89
125
|
if (gitServices.git === undefined)
|
90
|
-
|
126
|
+
process.exit(0);
|
91
127
|
config.gitServices = gitServices.git;
|
92
128
|
// Chequear las variables de entorno
|
93
129
|
if (gitServices.git === GitServices.GitHub && !process.env.GITHUB_TOKEN) {
|
@@ -107,7 +143,7 @@ export function createConfigurationFile() {
|
|
107
143
|
choices: models
|
108
144
|
}]);
|
109
145
|
if (automationModel.model === undefined)
|
110
|
-
return
|
146
|
+
return;
|
111
147
|
config.model = automationModel.model;
|
112
148
|
// Si es custom pregunta si quiere tomar de base alguno existente
|
113
149
|
if (automationModel.model === 'custom') {
|
@@ -131,7 +167,7 @@ export function createConfigurationFile() {
|
|
131
167
|
choices: projectChoices
|
132
168
|
}]);
|
133
169
|
if (projectServices.project === undefined)
|
134
|
-
return
|
170
|
+
return;
|
135
171
|
config.projectServices = projectServices.project;
|
136
172
|
;
|
137
173
|
if (projectServices.project === ProjectServices.GitHub || projectServices.project === ProjectServices.GitLab) {
|
@@ -143,7 +179,7 @@ export function createConfigurationFile() {
|
|
143
179
|
message: "Nombre de la columna donde se crean nuevos issues"
|
144
180
|
}]);
|
145
181
|
if (backlogColumn.backlogColumn === undefined)
|
146
|
-
return
|
182
|
+
return;
|
147
183
|
config.backlogColumn = backlogColumn.backlogColumn;
|
148
184
|
logInfo(`Por omision ser utilizan proyectos dentro de ${context.repositoryOwner} y ${context.repositoryRepo} `);
|
149
185
|
}
|
@@ -155,7 +191,7 @@ export function createConfigurationFile() {
|
|
155
191
|
message: "Id del proyecto"
|
156
192
|
}]);
|
157
193
|
if (projectId.projectId === undefined)
|
158
|
-
return
|
194
|
+
return;
|
159
195
|
config.projectId = projectId.projectId;
|
160
196
|
// Modelo de Dcumentacion
|
161
197
|
const modelsTemplates = readJsonSync(`${TEMPLATES_FOLDER}/models.json`);
|
@@ -167,14 +203,18 @@ export function createConfigurationFile() {
|
|
167
203
|
choices: modelsTemplates
|
168
204
|
}]);
|
169
205
|
if (modelTemplates.model === undefined)
|
170
|
-
return
|
206
|
+
return;
|
171
207
|
config.modelTemplates = modelTemplates.model;
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
}
|
208
|
+
return config;
|
209
|
+
});
|
210
|
+
}
|
211
|
+
export function createConfigurationFile(taskName) {
|
212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
213
|
+
const baseConfig = { backlogColumn: context.backlogColumn, model: context.model, modelTemplates: context.modelTemplates, gitServices: context.gitServices, projectServices: context.projectServices, projectId: context.projectId, listFilter: context.listFilter, listTemplate: context.listTemplate };
|
214
|
+
let config = taskName ? yield getTaskConfig(baseConfig) : yield getBaseConfig(baseConfig);
|
215
|
+
if (!config)
|
216
|
+
return false;
|
217
|
+
storeConfig(config);
|
178
218
|
return true;
|
179
219
|
});
|
180
220
|
}
|
@@ -193,7 +233,7 @@ export function getConfig(variable, defaultValue) {
|
|
193
233
|
}
|
194
234
|
return defaultValue;
|
195
235
|
}
|
196
|
-
export function storeConfig(
|
236
|
+
export function storeConfig(record) {
|
197
237
|
let config = {};
|
198
238
|
if (fs.existsSync(CONFIG_FILE)) {
|
199
239
|
const content = fs.readFileSync(CONFIG_FILE, "utf8");
|
@@ -204,8 +244,15 @@ export function storeConfig(variable, value) {
|
|
204
244
|
throw new Error(`Verifique que el ${CONFIG_FILE} sea json valido`);
|
205
245
|
}
|
206
246
|
}
|
207
|
-
|
208
|
-
|
247
|
+
for (const [variable, value] of Object.entries(record)) {
|
248
|
+
config[variable] = value;
|
249
|
+
}
|
250
|
+
try {
|
251
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
252
|
+
}
|
253
|
+
catch (_b) {
|
254
|
+
throw new Error(`No se pudo guardar la configuracion en ${CONFIG_FILE}`);
|
255
|
+
}
|
209
256
|
}
|
210
257
|
export function sortByName(objA, objB) {
|
211
258
|
return objA.Name > objB.Name ? 1 : objA.Name < objB.Name ? -1 : 0;
|
package/package.json
CHANGED
File without changes
|