virtual-code-owners 7.0.1 → 7.0.2

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/dist/cli.js CHANGED
@@ -24,61 +24,65 @@ Options:
24
24
  --dryRun Just validate inputs, don't generate
25
25
  outputs (default: false)
26
26
  -h, --help display help for command`;
27
- export function cli(pArguments = process.argv.slice(2), pOutStream = process.stdout, pErrorStream = process.stderr, pErrorExitCode = 1) {
28
- try {
29
- const lOptions = getOptions(pArguments);
30
- if (lOptions.help) {
31
- pOutStream.write(`${HELP_MESSAGE}${EOL}`);
32
- return;
33
- }
34
- if (lOptions.version) {
35
- pOutStream.write(`${VERSION}${EOL}`);
36
- return;
37
- }
38
- main(lOptions, pErrorStream);
27
+ export function cli(
28
+ pArguments = process.argv.slice(2),
29
+ pOutStream = process.stdout,
30
+ pErrorStream = process.stderr,
31
+ pErrorExitCode = 1,
32
+ ) {
33
+ try {
34
+ const lOptions = getOptions(pArguments);
35
+ if (lOptions.help) {
36
+ pOutStream.write(`${HELP_MESSAGE}${EOL}`);
37
+ return;
39
38
  }
40
- catch (pError) {
41
- pErrorStream.write(`${EOL}ERROR: ${pError.message}${EOL}${EOL}`);
42
- process.exitCode = pErrorExitCode;
39
+ if (lOptions.version) {
40
+ pOutStream.write(`${VERSION}${EOL}`);
41
+ return;
43
42
  }
43
+ main(lOptions, pErrorStream);
44
+ } catch (pError) {
45
+ pErrorStream.write(`${EOL}ERROR: ${pError.message}${EOL}${EOL}`);
46
+ process.exitCode = pErrorExitCode;
47
+ }
44
48
  }
45
49
  function getOptions(pArguments) {
46
- return parseArgs({
47
- args: pArguments,
48
- options: {
49
- virtualCodeOwners: {
50
- type: "string",
51
- short: "v",
52
- default: ".github/VIRTUAL-CODEOWNERS.txt",
53
- },
54
- virtualTeams: {
55
- type: "string",
56
- short: "t",
57
- default: ".github/virtual-teams.yml",
58
- },
59
- codeOwners: {
60
- type: "string",
61
- short: "c",
62
- default: ".github/CODEOWNERS",
63
- },
64
- emitLabeler: {
65
- type: "boolean",
66
- short: "l",
67
- default: false,
68
- },
69
- labelerLocation: {
70
- type: "string",
71
- default: ".github/labeler.yml",
72
- },
73
- dryRun: {
74
- type: "boolean",
75
- default: false,
76
- },
77
- help: { type: "boolean", short: "h", default: false },
78
- version: { type: "boolean", short: "V", default: false },
79
- },
80
- strict: true,
81
- allowPositionals: true,
82
- tokens: false,
83
- }).values;
50
+ return parseArgs({
51
+ args: pArguments,
52
+ options: {
53
+ virtualCodeOwners: {
54
+ type: "string",
55
+ short: "v",
56
+ default: ".github/VIRTUAL-CODEOWNERS.txt",
57
+ },
58
+ virtualTeams: {
59
+ type: "string",
60
+ short: "t",
61
+ default: ".github/virtual-teams.yml",
62
+ },
63
+ codeOwners: {
64
+ type: "string",
65
+ short: "c",
66
+ default: ".github/CODEOWNERS",
67
+ },
68
+ emitLabeler: {
69
+ type: "boolean",
70
+ short: "l",
71
+ default: false,
72
+ },
73
+ labelerLocation: {
74
+ type: "string",
75
+ default: ".github/labeler.yml",
76
+ },
77
+ dryRun: {
78
+ type: "boolean",
79
+ default: false,
80
+ },
81
+ help: { type: "boolean", short: "h", default: false },
82
+ version: { type: "boolean", short: "V", default: false },
83
+ },
84
+ strict: true,
85
+ allowPositionals: true,
86
+ tokens: false,
87
+ }).values;
84
88
  }
@@ -1,52 +1,63 @@
1
1
  import { EOL } from "node:os";
2
2
  import { isEmailIshUsername } from "../utensils.js";
3
- const DEFAULT_WARNING = `#${EOL}` +
4
- `# DO NOT EDIT - this file is generated and your edits will be overwritten${EOL}` +
5
- `#${EOL}` +
6
- `# To make changes:${EOL}` +
7
- `#${EOL}` +
8
- `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
9
- `# - and/ or add team members to .github/virtual-teams.yml${EOL}` +
10
- `# - run 'npx virtual-code-owners' (or 'npx virtual-code-owners --emitLabeler' if you also${EOL}` +
11
- `# want to generate a .github/labeler.yml)${EOL}` +
12
- `#${EOL}${EOL}`;
13
- export default function generateCodeOwners(pVirtualCodeOwners, pTeamMap, pGeneratedWarning = DEFAULT_WARNING) {
14
- return (pGeneratedWarning +
15
- pVirtualCodeOwners
16
- .filter((pLine) => pLine.type !== "ignorable-comment")
17
- .map((pLine) => generateLine(pLine, pTeamMap))
18
- .join(EOL));
3
+ const DEFAULT_WARNING =
4
+ `#${EOL}` +
5
+ `# DO NOT EDIT - this file is generated and your edits will be overwritten${EOL}` +
6
+ `#${EOL}` +
7
+ `# To make changes:${EOL}` +
8
+ `#${EOL}` +
9
+ `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
10
+ `# - and/ or add team members to .github/virtual-teams.yml${EOL}` +
11
+ `# - run 'npx virtual-code-owners' (or 'npx virtual-code-owners --emitLabeler' if you also${EOL}` +
12
+ `# want to generate a .github/labeler.yml)${EOL}` +
13
+ `#${EOL}${EOL}`;
14
+ export default function generateCodeOwners(
15
+ pVirtualCodeOwners,
16
+ pTeamMap,
17
+ pGeneratedWarning = DEFAULT_WARNING,
18
+ ) {
19
+ return (
20
+ pGeneratedWarning +
21
+ pVirtualCodeOwners
22
+ .filter((pLine) => pLine.type !== "ignorable-comment")
23
+ .map((pLine) => generateLine(pLine, pTeamMap))
24
+ .join(EOL)
25
+ );
19
26
  }
20
27
  function generateLine(pCSTLine, pTeamMap) {
21
- if (pCSTLine.type === "rule") {
22
- const lUserNames = uniq(pCSTLine.users.flatMap((pUser) => expandTeamToUserNames(pUser, pTeamMap)))
23
- .sort(compareUserNames)
24
- .join(" ");
25
- return (pCSTLine.filesPattern +
26
- pCSTLine.spaces +
27
- lUserNames +
28
- (pCSTLine.inlineComment ? ` #${pCSTLine.inlineComment}` : ""));
29
- }
30
- return pCSTLine.raw;
28
+ if (pCSTLine.type === "rule") {
29
+ const lUserNames = uniq(
30
+ pCSTLine.users.flatMap((pUser) => expandTeamToUserNames(pUser, pTeamMap)),
31
+ )
32
+ .sort(compareUserNames)
33
+ .join(" ");
34
+ return (
35
+ pCSTLine.filesPattern +
36
+ pCSTLine.spaces +
37
+ lUserNames +
38
+ (pCSTLine.inlineComment ? ` #${pCSTLine.inlineComment}` : "")
39
+ );
40
+ }
41
+ return pCSTLine.raw;
31
42
  }
32
43
  function expandTeamToUserNames(pUser, pTeamMap) {
33
- if (pUser.type == "virtual-team-name") {
34
- return stringifyTeamMembers(pTeamMap, pUser.bareName);
35
- }
36
- return [pUser.raw];
44
+ if (pUser.type === "virtual-team-name") {
45
+ return stringifyTeamMembers(pTeamMap, pUser.bareName);
46
+ }
47
+ return [pUser.raw];
37
48
  }
38
49
  function stringifyTeamMembers(pTeamMap, pTeamName) {
39
- return (pTeamMap[pTeamName] ?? []).map(userNameToCodeOwner);
50
+ return (pTeamMap[pTeamName] ?? []).map(userNameToCodeOwner);
40
51
  }
41
52
  function userNameToCodeOwner(pUserName) {
42
- if (isEmailIshUsername(pUserName)) {
43
- return pUserName;
44
- }
45
- return `@${pUserName}`;
53
+ if (isEmailIshUsername(pUserName)) {
54
+ return pUserName;
55
+ }
56
+ return `@${pUserName}`;
46
57
  }
47
58
  function compareUserNames(pLeftName, pRightName) {
48
- return pLeftName.toLowerCase() > pRightName.toLowerCase() ? 1 : -1;
59
+ return pLeftName.toLowerCase() > pRightName.toLowerCase() ? 1 : -1;
49
60
  }
50
61
  function uniq(pUserNames) {
51
- return Array.from(new Set(pUserNames));
62
+ return Array.from(new Set(pUserNames));
52
63
  }
@@ -1,46 +1,53 @@
1
1
  import { EOL } from "node:os";
2
- const DEFAULT_WARNING = `#${EOL}` +
3
- `# DO NOT EDIT - this file is generated and your edits will be overwritten${EOL}` +
4
- `#${EOL}` +
5
- `# To make changes:${EOL}` +
6
- `#${EOL}` +
7
- `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
8
- `# - and/ or add teams (& members) to .github/virtual-teams.yml${EOL}` +
9
- `# - run 'npx virtual-code-owners --emitLabeler'${EOL}` +
10
- `#${EOL}${EOL}`;
11
- export default function generateLabelerYml(pCodeOwners, pTeamMap, pGeneratedWarning = DEFAULT_WARNING) {
12
- let lReturnValue = pGeneratedWarning;
13
- for (const lTeamName in pTeamMap) {
14
- const lPatternsForTeam = getPatternsForTeam(pCodeOwners, lTeamName)
15
- .map((pPattern) => ` - ${transformForYamlAndMinimatch(pPattern)}${EOL}`)
16
- .join("");
17
- if (lPatternsForTeam) {
18
- lReturnValue += `${lTeamName}:${EOL}${lPatternsForTeam}${EOL}`;
19
- }
2
+ const DEFAULT_WARNING =
3
+ `#${EOL}` +
4
+ `# DO NOT EDIT - this file is generated and your edits will be overwritten${EOL}` +
5
+ `#${EOL}` +
6
+ `# To make changes:${EOL}` +
7
+ `#${EOL}` +
8
+ `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
9
+ `# - and/ or add teams (& members) to .github/virtual-teams.yml${EOL}` +
10
+ `# - run 'npx virtual-code-owners --emitLabeler'${EOL}` +
11
+ `#${EOL}${EOL}`;
12
+ export default function generateLabelerYml(
13
+ pCodeOwners,
14
+ pTeamMap,
15
+ pGeneratedWarning = DEFAULT_WARNING,
16
+ ) {
17
+ let lReturnValue = pGeneratedWarning;
18
+ for (const lTeamName in pTeamMap) {
19
+ const lPatternsForTeam = getPatternsForTeam(pCodeOwners, lTeamName)
20
+ .map((pPattern) => ` - ${transformForYamlAndMinimatch(pPattern)}${EOL}`)
21
+ .join("");
22
+ if (lPatternsForTeam) {
23
+ lReturnValue += `${lTeamName}:${EOL}${lPatternsForTeam}${EOL}`;
20
24
  }
21
- return lReturnValue;
25
+ }
26
+ return lReturnValue;
22
27
  }
23
28
  function getPatternsForTeam(pCodeOwners, pTeamName) {
24
- return (pCodeOwners
25
- .filter((pLine) => {
26
- return (pLine.type === "rule" &&
27
- lineContainsTeamName(pLine, pTeamName));
29
+ return pCodeOwners
30
+ .filter((pLine) => {
31
+ return pLine.type === "rule" && lineContainsTeamName(pLine, pTeamName);
28
32
  })
29
- .map((pLine) => pLine.filesPattern));
33
+ .map((pLine) => pLine.filesPattern);
30
34
  }
31
35
  function transformForYamlAndMinimatch(pOriginalString) {
32
- let lReturnValue = pOriginalString;
33
- if (pOriginalString === "*") {
34
- lReturnValue = "**";
35
- }
36
- if (lReturnValue.startsWith("*")) {
37
- lReturnValue = `"${lReturnValue}"`;
38
- }
39
- if (pOriginalString.endsWith("/")) {
40
- lReturnValue = `${lReturnValue}**`;
41
- }
42
- return lReturnValue;
36
+ let lReturnValue = pOriginalString;
37
+ if (pOriginalString === "*") {
38
+ lReturnValue = "**";
39
+ }
40
+ if (lReturnValue.startsWith("*")) {
41
+ lReturnValue = `"${lReturnValue}"`;
42
+ }
43
+ if (pOriginalString.endsWith("/")) {
44
+ lReturnValue = `${lReturnValue}**`;
45
+ }
46
+ return lReturnValue;
43
47
  }
44
48
  function lineContainsTeamName(pLine, pTeamName) {
45
- return pLine.users.some((pUser) => pUser.type === "virtual-team-name" && pUser.bareName === pTeamName);
49
+ return pLine.users.some(
50
+ (pUser) =>
51
+ pUser.type === "virtual-team-name" && pUser.bareName === pTeamName,
52
+ );
46
53
  }
package/dist/main.js CHANGED
@@ -5,24 +5,28 @@ import generateLabelerYml from "./labeler-yml/generate.js";
5
5
  import readTeamMap from "./team-map/read.js";
6
6
  import readVirtualCodeOwners from "./virtual-code-owners/read.js";
7
7
  export function main(pOptions, pErrorStream) {
8
- const lTeamMap = readTeamMap(pOptions.virtualTeams);
9
- const lVirtualCodeOwners = readVirtualCodeOwners(pOptions.virtualCodeOwners, lTeamMap);
10
- const lCodeOwnersContent = generateCodeOwners(lVirtualCodeOwners, lTeamMap);
8
+ const lTeamMap = readTeamMap(pOptions.virtualTeams);
9
+ const lVirtualCodeOwners = readVirtualCodeOwners(
10
+ pOptions.virtualCodeOwners,
11
+ lTeamMap,
12
+ );
13
+ const lCodeOwnersContent = generateCodeOwners(lVirtualCodeOwners, lTeamMap);
14
+ if (!pOptions.dryRun) {
15
+ writeFileSync(pOptions.codeOwners, lCodeOwnersContent, {
16
+ encoding: "utf-8",
17
+ });
18
+ }
19
+ if (pOptions.emitLabeler) {
20
+ const lLabelerContent = generateLabelerYml(lVirtualCodeOwners, lTeamMap);
11
21
  if (!pOptions.dryRun) {
12
- writeFileSync(pOptions.codeOwners, lCodeOwnersContent, {
13
- encoding: "utf-8",
14
- });
15
- }
16
- if (pOptions.emitLabeler) {
17
- const lLabelerContent = generateLabelerYml(lVirtualCodeOwners, lTeamMap);
18
- if (!pOptions.dryRun) {
19
- writeFileSync(pOptions.labelerLocation, lLabelerContent, {
20
- encoding: "utf-8",
21
- });
22
- }
23
- pErrorStream.write(`${EOL}Wrote '${pOptions.codeOwners}' AND '${pOptions.labelerLocation}'${EOL}${EOL}`);
24
- }
25
- else {
26
- pErrorStream.write(`${EOL}Wrote '${pOptions.codeOwners}'${EOL}${EOL}`);
22
+ writeFileSync(pOptions.labelerLocation, lLabelerContent, {
23
+ encoding: "utf-8",
24
+ });
27
25
  }
26
+ pErrorStream.write(
27
+ `${EOL}Wrote '${pOptions.codeOwners}' AND '${pOptions.labelerLocation}'${EOL}${EOL}`,
28
+ );
29
+ } else {
30
+ pErrorStream.write(`${EOL}Wrote '${pOptions.codeOwners}'${EOL}${EOL}`);
31
+ }
28
32
  }
@@ -4,27 +4,34 @@ import { EOL } from "node:os";
4
4
  import { parse as parseYaml } from "yaml";
5
5
  import virtualTeamsSchema from "./virtual-teams.schema.js";
6
6
  export default function readTeamMap(pVirtualTeamsFileName) {
7
- const lVirtualTeamsAsAString = readFileSync(pVirtualTeamsFileName, {
8
- encoding: "utf-8",
9
- });
10
- const lTeamMap = parseYaml(lVirtualTeamsAsAString);
11
- assertTeamMapValid(lTeamMap, pVirtualTeamsFileName);
12
- return lTeamMap;
7
+ const lVirtualTeamsAsAString = readFileSync(pVirtualTeamsFileName, {
8
+ encoding: "utf-8",
9
+ });
10
+ const lTeamMap = parseYaml(lVirtualTeamsAsAString);
11
+ assertTeamMapValid(lTeamMap, pVirtualTeamsFileName);
12
+ return lTeamMap;
13
13
  }
14
14
  function assertTeamMapValid(pTeamMap, pVirtualTeamsFileName) {
15
- const ajv = new Ajv({
16
- allErrors: true,
17
- verbose: true,
18
- });
19
- if (!ajv.validate(virtualTeamsSchema, pTeamMap)) {
20
- throw new Error(`This is not a valid virtual-teams.yml:${EOL}${formatAjvErrors(ajv.errors, pVirtualTeamsFileName)}.\n`);
21
- }
15
+ const ajv = new Ajv({
16
+ allErrors: true,
17
+ verbose: true,
18
+ });
19
+ if (!ajv.validate(virtualTeamsSchema, pTeamMap)) {
20
+ throw new Error(
21
+ `This is not a valid virtual-teams.yml:${EOL}${formatAjvErrors(
22
+ ajv.errors,
23
+ pVirtualTeamsFileName,
24
+ )}.\n`,
25
+ );
26
+ }
22
27
  }
23
28
  function formatAjvErrors(pAjvErrors, pVirtualTeamsFileName) {
24
- return pAjvErrors
25
- .map((pAjvError) => formatAjvError(pAjvError, pVirtualTeamsFileName))
26
- .join(EOL);
29
+ return pAjvErrors
30
+ .map((pAjvError) => formatAjvError(pAjvError, pVirtualTeamsFileName))
31
+ .join(EOL);
27
32
  }
28
33
  function formatAjvError(pAjvError, pVirtualTeamsFileName) {
29
- return `${pVirtualTeamsFileName}: ${pAjvError.instancePath} - ${JSON.stringify(pAjvError.data)} ${pAjvError.message}`;
34
+ return `${pVirtualTeamsFileName}: ${
35
+ pAjvError.instancePath
36
+ } - ${JSON.stringify(pAjvError.data)} ${pAjvError.message}`;
30
37
  }
@@ -1,15 +1,16 @@
1
1
  export default {
2
- $schema: "http://json-schema.org/draft-07/schema#",
3
- title: "virtual teams schema for virtual-code-owners",
4
- description: "a list of teams and their team members",
5
- $id: "org.js.virtual-code-owners/7.0.0",
6
- type: "object",
7
- additionalProperties: {
8
- type: "array",
9
- items: {
10
- type: "string",
11
- description: "Username or e-mail address of a team member. (Don't prefix usernames with '@')",
12
- pattern: "^[^@][^\\s]+$",
13
- },
2
+ $schema: "http://json-schema.org/draft-07/schema#",
3
+ title: "virtual teams schema for virtual-code-owners",
4
+ description: "a list of teams and their team members",
5
+ $id: "org.js.virtual-code-owners/7.0.0",
6
+ type: "object",
7
+ additionalProperties: {
8
+ type: "array",
9
+ items: {
10
+ type: "string",
11
+ description:
12
+ "Username or e-mail address of a team member. (Don't prefix usernames with '@')",
13
+ pattern: "^[^@][^\\s]+$",
14
14
  },
15
+ },
15
16
  };
package/dist/utensils.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export function isEmailIshUsername(pUsername) {
2
- const lEmailIshUsernameRE = /^.+@.+$/;
3
- return Boolean(pUsername.match(lEmailIshUsernameRE));
2
+ const lEmailIshUsernameRE = /^.+@.+$/;
3
+ return Boolean(pUsername.match(lEmailIshUsernameRE));
4
4
  }
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "7.0.1";
1
+ export const VERSION = "7.0.2";
@@ -1,31 +1,32 @@
1
1
  export function getAnomalies(pVirtualCodeOwners) {
2
- const weirdLines = pVirtualCodeOwners
3
- .filter((pLine) => pLine.type === "unknown")
4
- .map((pLine) => ({
5
- ...pLine,
6
- type: "invalid-line",
2
+ const weirdLines = pVirtualCodeOwners
3
+ .filter((pLine) => pLine.type === "unknown")
4
+ .map((pLine) => ({
5
+ ...pLine,
6
+ type: "invalid-line",
7
7
  }));
8
- const weirdUsers = pVirtualCodeOwners.flatMap((pLine) => {
9
- if (pLine.type === "rule") {
10
- return pLine.users
11
- .filter((pUser) => pUser.type === "invalid")
12
- .map((pUser) => ({
13
- ...pUser,
14
- line: pLine.line,
15
- type: "invalid-user",
16
- }));
17
- }
18
- return [];
19
- });
20
- return weirdLines.concat(weirdUsers).sort(orderAnomaly);
8
+ const weirdUsers = pVirtualCodeOwners.flatMap((pLine) => {
9
+ if (pLine.type === "rule") {
10
+ return pLine.users
11
+ .filter((pUser) => pUser.type === "invalid")
12
+ .map((pUser) => ({
13
+ ...pUser,
14
+ line: pLine.line,
15
+ type: "invalid-user",
16
+ }));
17
+ }
18
+ return [];
19
+ });
20
+ return weirdLines.concat(weirdUsers).sort(orderAnomaly);
21
21
  }
22
22
  function orderAnomaly(pLeft, pRight) {
23
- if (pLeft.line === pRight.line &&
24
- pLeft.type === "invalid-user" &&
25
- pRight.type === "invalid-user") {
26
- return pLeft.userNumberWithinLine > pRight.userNumberWithinLine ? 1 : -1;
27
- }
28
- else {
29
- return pLeft.line > pRight.line ? 1 : -1;
30
- }
23
+ if (
24
+ pLeft.line === pRight.line &&
25
+ pLeft.type === "invalid-user" &&
26
+ pRight.type === "invalid-user"
27
+ ) {
28
+ return pLeft.userNumberWithinLine > pRight.userNumberWithinLine ? 1 : -1;
29
+ } else {
30
+ return pLeft.line > pRight.line ? 1 : -1;
31
+ }
31
32
  }
@@ -1,63 +1,67 @@
1
1
  import { EOL } from "node:os";
2
2
  import { isEmailIshUsername } from "../utensils.js";
3
3
  export function parse(pVirtualCodeOwnersAsString, pTeamMap = {}) {
4
- return pVirtualCodeOwnersAsString
5
- .split(EOL)
6
- .map((pUntreatedLine, pLineNo) => parseLine(pUntreatedLine, pTeamMap, pLineNo + 1));
4
+ return pVirtualCodeOwnersAsString
5
+ .split(EOL)
6
+ .map((pUntreatedLine, pLineNo) =>
7
+ parseLine(pUntreatedLine, pTeamMap, pLineNo + 1),
8
+ );
7
9
  }
8
10
  function parseLine(pUntreatedLine, pTeamMap, pLineNo) {
9
- const lTrimmedLine = pUntreatedLine.trim();
10
- const lCommentSplitLine = lTrimmedLine.split(/\s*#/);
11
- const lRule = lCommentSplitLine[0]?.match(/^(?<filesPattern>[^\s]+)(?<spaces>\s+)(?<userNames>.*)$/);
12
- if (lTrimmedLine.startsWith("#!")) {
13
- return { type: "ignorable-comment", line: pLineNo, raw: pUntreatedLine };
11
+ const lTrimmedLine = pUntreatedLine.trim();
12
+ const lCommentSplitLine = lTrimmedLine.split(/\s*#/);
13
+ const lRule = lCommentSplitLine[0]?.match(
14
+ /^(?<filesPattern>[^\s]+)(?<spaces>\s+)(?<userNames>.*)$/,
15
+ );
16
+ if (lTrimmedLine.startsWith("#!")) {
17
+ return { type: "ignorable-comment", line: pLineNo, raw: pUntreatedLine };
18
+ }
19
+ if (lTrimmedLine.startsWith("#")) {
20
+ return { type: "comment", line: pLineNo, raw: pUntreatedLine };
21
+ }
22
+ if (!lRule?.groups) {
23
+ if (lTrimmedLine === "") {
24
+ return { type: "empty", line: pLineNo, raw: pUntreatedLine };
14
25
  }
15
- if (lTrimmedLine.startsWith("#")) {
16
- return { type: "comment", line: pLineNo, raw: pUntreatedLine };
17
- }
18
- if (!lRule?.groups) {
19
- if (lTrimmedLine === "") {
20
- return { type: "empty", line: pLineNo, raw: pUntreatedLine };
21
- }
22
- return { type: "unknown", line: pLineNo, raw: pUntreatedLine };
23
- }
24
- return {
25
- type: "rule",
26
- line: pLineNo,
27
- filesPattern: lRule.groups.filesPattern,
28
- spaces: lRule.groups.spaces,
29
- users: parseUsers(lRule.groups.userNames, pTeamMap),
30
- inlineComment: lCommentSplitLine[1] ?? "",
31
- raw: pUntreatedLine,
32
- };
26
+ return { type: "unknown", line: pLineNo, raw: pUntreatedLine };
27
+ }
28
+ return {
29
+ type: "rule",
30
+ line: pLineNo,
31
+ filesPattern: lRule.groups.filesPattern,
32
+ spaces: lRule.groups.spaces,
33
+ users: parseUsers(lRule.groups.userNames, pTeamMap),
34
+ inlineComment: lCommentSplitLine[1] ?? "",
35
+ raw: pUntreatedLine,
36
+ };
33
37
  }
34
38
  function parseUsers(pUserNamesString, pTeamMap) {
35
- const lUserNames = pUserNamesString.split(/\s+/);
36
- return lUserNames.map((pUserName, pIndex) => {
37
- const lBareName = getBareUserName(pUserName);
38
- return {
39
- type: getUserNameType(pUserName, lBareName, pTeamMap),
40
- userNumberWithinLine: pIndex + 1,
41
- bareName: lBareName,
42
- raw: pUserName,
43
- };
44
- });
39
+ const lUserNames = pUserNamesString.split(/\s+/);
40
+ return lUserNames.map((pUserName, pIndex) => {
41
+ const lBareName = getBareUserName(pUserName);
42
+ return {
43
+ type: getUserNameType(pUserName, lBareName, pTeamMap),
44
+ userNumberWithinLine: pIndex + 1,
45
+ bareName: lBareName,
46
+ raw: pUserName,
47
+ };
48
+ });
45
49
  }
46
50
  function getUserNameType(pUserName, pBareName, pTeamMap) {
47
- if (isEmailIshUsername(pUserName)) {
48
- return "e-mail-address";
51
+ if (isEmailIshUsername(pUserName)) {
52
+ return "e-mail-address";
53
+ }
54
+ if (pUserName.startsWith("@")) {
55
+ if (pTeamMap.hasOwnProperty(pBareName)) {
56
+ return "virtual-team-name";
49
57
  }
50
- if (pUserName.startsWith("@")) {
51
- if (pTeamMap.hasOwnProperty(pBareName)) {
52
- return "virtual-team-name";
53
- }
54
- return "other-user-or-team";
55
- }
56
- return "invalid";
58
+ return "other-user-or-team";
59
+ }
60
+ return "invalid";
57
61
  }
58
62
  function getBareUserName(pUserName) {
59
- if (pUserName.startsWith("@")) {
60
- return pUserName.slice(1);
61
- }
62
- return pUserName;
63
+ if (pUserName.startsWith("@")) {
64
+ return pUserName.slice(1);
65
+ }
66
+ return pUserName;
63
67
  }
@@ -2,27 +2,39 @@ import { readFileSync } from "node:fs";
2
2
  import { EOL } from "node:os";
3
3
  import { getAnomalies } from "./anomalies.js";
4
4
  import { parse as parseVirtualCodeOwners } from "./parse.js";
5
- export default function readVirtualCodeOwners(pVirtualCodeOwnersFileName, pTeamMap) {
6
- const lVirtualCodeOwnersAsAString = readFileSync(pVirtualCodeOwnersFileName, {
7
- encoding: "utf-8",
8
- });
9
- const lVirtualCodeOwners = parseVirtualCodeOwners(lVirtualCodeOwnersAsAString, pTeamMap);
10
- const lAnomalies = getAnomalies(lVirtualCodeOwners);
11
- if (lAnomalies.length > 0) {
12
- throw new Error(`This is not a valid virtual code-owners file:${EOL}${reportAnomalies(pVirtualCodeOwnersFileName, lAnomalies)}`);
13
- }
14
- return lVirtualCodeOwners;
5
+ export default function readVirtualCodeOwners(
6
+ pVirtualCodeOwnersFileName,
7
+ pTeamMap,
8
+ ) {
9
+ const lVirtualCodeOwnersAsAString = readFileSync(pVirtualCodeOwnersFileName, {
10
+ encoding: "utf-8",
11
+ });
12
+ const lVirtualCodeOwners = parseVirtualCodeOwners(
13
+ lVirtualCodeOwnersAsAString,
14
+ pTeamMap,
15
+ );
16
+ const lAnomalies = getAnomalies(lVirtualCodeOwners);
17
+ if (lAnomalies.length > 0) {
18
+ throw new Error(
19
+ `This is not a valid virtual code-owners file:${EOL}${reportAnomalies(
20
+ pVirtualCodeOwnersFileName,
21
+ lAnomalies,
22
+ )}`,
23
+ );
24
+ }
25
+ return lVirtualCodeOwners;
15
26
  }
16
27
  function reportAnomalies(pFileName, pAnomalies) {
17
- return pAnomalies
18
- .map((pAnomaly) => {
19
- if (pAnomaly.type === "invalid-line") {
20
- return `${pFileName}:${pAnomaly.line}:1 invalid line - neither a rule, comment nor empty: "${pAnomaly.raw}"`;
21
- }
22
- else {
23
- return (`${pFileName}:${pAnomaly.line}:1 invalid user or team name "${pAnomaly.raw}" (#${pAnomaly.userNumberWithinLine} on this line). ` +
24
- `It should either start with "@" or be an e-mail address.`);
25
- }
28
+ return pAnomalies
29
+ .map((pAnomaly) => {
30
+ if (pAnomaly.type === "invalid-line") {
31
+ return `${pFileName}:${pAnomaly.line}:1 invalid line - neither a rule, comment nor empty: "${pAnomaly.raw}"`;
32
+ } else {
33
+ return (
34
+ `${pFileName}:${pAnomaly.line}:1 invalid user or team name "${pAnomaly.raw}" (#${pAnomaly.userNumberWithinLine} on this line). ` +
35
+ `It should either start with "@" or be an e-mail address.`
36
+ );
37
+ }
26
38
  })
27
- .join(EOL);
39
+ .join(EOL);
28
40
  }
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "virtual-code-owners",
3
- "version": "7.0.1",
3
+ "version": "7.0.2",
4
4
  "description": "Makes your CODEOWNERS file liveable again",
5
5
  "type": "module",
6
- "bin": "dist/run-cli.js",
6
+ "bin": {
7
+ "virtual-code-owners": "dist/run-cli.js"
8
+ },
7
9
  "files": [
8
10
  "dist/",
9
11
  "package.json",
@@ -25,7 +27,7 @@
25
27
  },
26
28
  "dependencies": {
27
29
  "ajv": "8.12.0",
28
- "yaml": "2.3.3"
30
+ "yaml": "2.3.4"
29
31
  },
30
32
  "engines": {
31
33
  "node": "^18.11.0||>=20.0.0"