Skip to content
This repository was archived by the owner on May 4, 2023. It is now read-only.

Commit 148d575

Browse files
Merge pull request #4 from codiga/feat/interactive-rulesets
Interactive ruleset selection (including multi inputs)
2 parents 8c80891 + bf306c5 commit 148d575

File tree

17 files changed

+655
-134
lines changed

17 files changed

+655
-134
lines changed

graphql/queries.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,3 @@ export const GET_RULESETS_FOR_CLIENT = gql`
2727
}
2828
}
2929
`;
30-
31-
export const GET_RULESET = gql`
32-
query getRuleset($name: String!) {
33-
ruleSet(name: $name) {
34-
id
35-
name
36-
}
37-
}
38-
`;

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codiga/cli",
3-
"version": "1.0.8",
3+
"version": "1.0.9",
44
"description": "A Codiga CLI used to integrate Codiga easily in your projects",
55
"homepage": "https://github.com/codiga/codiga-cli",
66
"repository": {

src/addRuleset.js

Lines changed: 99 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import {
1212
printEmptyLine,
1313
printFailure,
1414
printInfo,
15+
printSubItem,
1516
printSuggestion,
1617
} from "../utils/print";
17-
import { convertRulesetsToString, getRuleset } from "../utils/ruleset";
18+
import { convertRulesetsToString } from "../utils/rulesets";
19+
import { getRulesetsByNames, getUserPromptedRulesets } from "../utils/rulesets";
1820

1921
/**
2022
* Creates a codiga.yml file's content with the rulesets given
@@ -44,39 +46,65 @@ export async function createCodigaYml(codigaFileLocation, rulesets) {
4446
* Handles adding a ruleset to a codiga.yml file
4547
* @param {string[]} rulesetNames
4648
*/
47-
export async function addRuleset(rulesetNames) {
48-
// TODO - change to a prompt when no rulesets are given
49-
const rulesetName = rulesetNames[0];
50-
if (!rulesetName) {
49+
export async function addRuleset(rulesetNamesParams) {
50+
let rulesetNames = rulesetNamesParams;
51+
52+
/**
53+
* if `codiga ruleset-add` was called with no rulesets, we'll
54+
* open an interactive menu for them to select suggested rulesets
55+
*/
56+
if (rulesetNamesParams.length === 0) {
57+
// prompt the user to choose some rulesets
58+
rulesetNames = await getUserPromptedRulesets();
59+
// if the user didn't choose any notify them and exit
60+
if (rulesetNames.length === 0) {
61+
printEmptyLine();
62+
printInfo("No rulesets were chosen.");
63+
printCommandSuggestion(
64+
" ↳ Run the command again to get started:",
65+
ACTION_RULESET_ADD
66+
);
67+
printSuggestion(
68+
" ↳ Find all publically available rulesets here:",
69+
"https://app.codiga.io/hub/rulesets"
70+
);
71+
printEmptyLine();
72+
process.exit(1);
73+
}
74+
}
75+
76+
/**
77+
* Here we take the ruleset names that were chosen through the interactive
78+
* mode or were received from the command parameters, and validate which
79+
* ones are valid and should be added to a `codiga.yml` file and which
80+
* we should inform the user won't be added
81+
*/
82+
83+
const { found: validRulesets, notFound } = await getRulesetsByNames(
84+
rulesetNames
85+
);
86+
87+
if (notFound.length > 0) {
5188
printEmptyLine();
52-
printFailure("You need to specify a ruleset to add");
53-
printSuggestion(
54-
" ↳ You can search for rulesets here:",
55-
"https://app.codiga.io/hub/rulesets"
89+
printFailure(
90+
"The following rulesets either don't exist or you lack the permissions to access it:"
5691
);
92+
notFound.forEach((notFoundRuleset) => {
93+
printSubItem(`- ${notFoundRuleset}`);
94+
});
5795
printCommandSuggestion(
58-
" ↳ Then follow this command structure:",
59-
`${ACTION_RULESET_ADD} <ruleset-name>`
96+
"Ensure you have a Codiga API token set with one of the following commands:",
97+
ACTION_TOKEN_ADD
6098
);
61-
printEmptyLine();
62-
process.exit(1);
6399
}
64100

65-
// Check if the ruleset exists before continuing onwards
66-
const ruleset = await getRuleset({ name: rulesetName });
67-
if (!ruleset) {
101+
if (validRulesets.length === 0) {
68102
printEmptyLine();
69-
printFailure(
70-
"That ruleset either doesn't exist or you lack the permissions to access it"
71-
);
103+
printInfo("No valid rulesets were found to continue");
72104
printCommandSuggestion(
73105
" ↳ Ensure you have a Codiga API token set with one of the following commands:",
74106
ACTION_TOKEN_ADD
75107
);
76-
printSuggestion(
77-
" ↳ You can find more rulesets here:",
78-
"https://app.codiga.io/hub/rulesets"
79-
);
80108
printEmptyLine();
81109
process.exit(1);
82110
}
@@ -92,46 +120,71 @@ export async function addRuleset(rulesetNames) {
92120
const codigaFileContent = readFile(codigaFileLocation);
93121

94122
/**
95-
* If we found a `codiga.yml` file, add the rule to it
96-
* If we don't find a `codiga.yml` file, create the file and add the rule to it
123+
* If we found a `codiga.yml` file, add the new rulesets to it
124+
* If we don't find a `codiga.yml` file, create the file and add the rulesets to it
97125
*/
98126
if (codigaFileContent) {
99127
const parsedFile = parseYamlFile(codigaFileContent, codigaFileLocation);
100128
const codigaRulesets = parsedFile.rulesets;
101-
if (codigaRulesets.includes(rulesetName)) {
129+
130+
// check which rulesets are new and which are already used in the `codiga.yml` file
131+
const { usedRulesets, newRulesets } = validRulesets.reduce(
132+
(acc, ruleset) => {
133+
if (codigaRulesets.includes(ruleset)) {
134+
acc.usedRulesets.push(ruleset);
135+
} else {
136+
acc.newRulesets.push(ruleset);
137+
}
138+
return acc;
139+
},
140+
{
141+
usedRulesets: [],
142+
newRulesets: [],
143+
}
144+
);
145+
146+
if (usedRulesets.length > 0) {
102147
printEmptyLine();
103148
printInfo(
104-
`The ruleset (${rulesetName}) already exists in your \`codiga.yml\``
105-
);
106-
printSuggestion;
107-
printEmptyLine();
108-
process.exit(1);
109-
} else {
110-
// adding the new ruleset to the file
111-
await createCodigaYml(codigaFileLocation, [
112-
...codigaRulesets,
113-
rulesetName,
114-
]);
115-
printSuggestion(
116-
`We added ${rulesetName} to your codiga.yml file:`,
117-
codigaFileLocation
118-
);
119-
printSuggestion(
120-
" ↳ Find more rulesets to add here:",
121-
"https://app.codiga.io/hub/rulesets"
149+
`The following rulesets already exists in your \`codiga.yml\` file:`
122150
);
151+
usedRulesets.forEach((ruleset) => {
152+
printSubItem(`- ${ruleset}`);
153+
});
123154
}
155+
156+
// adding the new ruleset to the file
157+
await createCodigaYml(codigaFileLocation, [
158+
...codigaRulesets,
159+
...newRulesets,
160+
]);
161+
printEmptyLine();
162+
printSuggestion(
163+
`We added ${newRulesets.length} ruleset${
164+
newRulesets.length === 1 ? "" : "s"
165+
} to your codiga.yml file:`,
166+
codigaFileLocation
167+
);
168+
printSuggestion(
169+
" ↳ Find more rulesets to add here:",
170+
"https://app.codiga.io/hub/rulesets"
171+
);
172+
printEmptyLine();
124173
} else {
125174
// creating a new codiga.yml with the ruleset here
126-
await createCodigaYml(codigaFileLocation, [rulesetName]);
175+
await createCodigaYml(codigaFileLocation, validRulesets);
176+
printEmptyLine();
127177
printSuggestion(
128-
`No codiga.yml file found, so we created one and added ${rulesetName} to it:`,
178+
`No codiga.yml file found, so we created one and added ${
179+
validRulesets.length
180+
} ruleset${validRulesets.length === 1 ? "" : "s"} to it:`,
129181
codigaFileLocation
130182
);
131183
printSuggestion(
132184
" ↳ Find more rulesets to add here:",
133185
"https://app.codiga.io/hub/rulesets"
134186
);
187+
printEmptyLine();
135188
}
136189

137190
process.exit(0);

src/cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function parseCommand(args) {
5252
},
5353
}
5454
)
55-
.command(ACTION_RULESET_ADD, "Add a ruleset to a `codiga.yml` file")
55+
.command(ACTION_RULESET_ADD, "Add rulesets to a `codiga.yml` file")
5656
.help(true).argv;
5757

5858
// format any actions into a single object with default values

tests/__mocks__/inquirer.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ exports.prompt = (prompts) => {
4242
a.choices.forEach((c, i) => {
4343
const expected = a.choices[i];
4444
if (expected) {
45-
expect(prompt.choices[i].name).toContain(expected);
45+
expect(prompt.choices[i]).toEqual(expected);
4646
}
4747
});
4848
}
@@ -54,12 +54,20 @@ exports.prompt = (prompts) => {
5454

5555
if (a.choose != null) {
5656
expect(prompt.type).toBe("list");
57-
setValue(prompt.choices[a.choose].value);
57+
setValue(
58+
prompt.choices.find((choice) => choice.value === a.choose)?.value
59+
);
5860
}
5961

6062
if (a.check != null) {
6163
expect(prompt.type).toBe("checkbox");
62-
setValue(a.check.map((i) => prompt.choices[i].value));
64+
setValue(
65+
a.check
66+
.map((check) => {
67+
return prompt.choices.find((choice) => choice.name === check)?.name;
68+
})
69+
.filter((c) => c)
70+
);
6371
}
6472

6573
if (a.confirm != null) {

0 commit comments

Comments
 (0)