virtual-code-owners 1.0.0 → 2.1.0

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/README.md CHANGED
@@ -5,16 +5,25 @@ This takes a
5
5
  - VIRTUAL-CODEOWNERS.txt file with (virtual) teams
6
6
  - a `virtual-teams.yml` file which define the teams
7
7
 
8
- ... and churns out a CODEOWNERS with user names.
8
+ ... and merges them into a CODEOWNERS with user names.
9
9
 
10
10
  ## Usage
11
11
 
12
- - Rename your `CODEOWNERS` to `VIRTUAL-CODEOWNERS.txt` and put team names in them.
13
- - Specify team names that don't (yet) exist on GitHub level in a `virtual-teams.yml`
12
+ - Rename your `.github/CODEOWNERS` to `.github/VIRTUAL-CODEOWNERS.txt` and put team names in them.
13
+ - Specify team names that don't (yet) exist on GitHub level in a `.github/virtual-teams.yml`
14
14
  - Run this:
15
15
 
16
16
  ```
17
- npx virtual-code-owners VIRTUAL-CODEOWNERS.txt virtual-teams.yml > .github/CODEOWNERS
17
+ npx virtual-code-owners
18
+ ```
19
+
20
+ or, if you want to be verbose
21
+
22
+ ```
23
+ npx virtual-code-owners \
24
+ --virtual-code-owners .github/VIRTUAL-CODEOWNERS.txt \
25
+ --virtual-teams .github/virtual-teams.yml \
26
+ --code-owners .github/CODEOWNERS
18
27
  ```
19
28
 
20
29
  ## Why?
@@ -43,6 +52,12 @@ the _teams_ the former uses might not exist yet, except in a `virtual-teams.yml`
43
52
  Example:
44
53
 
45
54
  ```
55
+ #! comments that start with #! won't appear in the CODEOWNERS output e.g.
56
+ #! this is not the CODEOWNERS file - to get that one run
57
+ #! npx virtual-code-owners VIRTUAL-CODE-OWNERS.txt virtual-teams.yml > CODEOWNERS
58
+ #! on this.
59
+ #!
60
+ # Regular comments are retained
46
61
  * @cloud-heroes-all
47
62
  .github/ @ch/transversal
48
63
  apps/broker @ch/transversal
@@ -88,7 +103,7 @@ It might be you already have a team or two defined, but just want to use
88
103
  _additional_ teams. In that case just don't specify the already-defined teams
89
104
  in `virtual-teams.yml` and _virtual-code-owners_ will leave them alone.
90
105
 
91
- ### Can I still use usernames in `VIRTUAL-CODEOWNERS.txt`
106
+ ### Can I still use usernames in `VIRTUAL-CODEOWNERS.txt`?
92
107
 
93
108
  Yes.
94
109
 
@@ -117,3 +132,18 @@ present on text files.
117
132
 
118
133
  Apparently these editors know about CODEOWNERS, though so this auto formatting
119
134
  doesn't seem to be happening over there.
135
+
136
+ ### Do I have to run this each time I edit `VIRTUAL-CODEOWNERS.txt`?
137
+
138
+ Yes. But please automate this for your own sake.
139
+
140
+ You can for instance set up a rule for `lint-staged` in a `.lintstagedrc.json`
141
+ like this:
142
+
143
+ ```json
144
+ {
145
+ ".github/VIRTUAL-CODEOWNERS.txt|.github/virtual-teams.yml": [
146
+ "npx virtual-code-owners"
147
+ ]
148
+ }
149
+ ```
package/dist/cli.js CHANGED
@@ -2,14 +2,23 @@
2
2
  import { program } from "commander";
3
3
  import { VERSION } from "./version.js";
4
4
  import { readAndConvert } from "./read-and-convert.js";
5
+ import { writeFileSync } from "node:fs";
6
+ import { EOL } from "node:os";
5
7
  program
6
- .description("Takes a VIRTUAL-CODEOWNERS.txt & a virtual-teams.yml and emits a CODEOWNERS to stdout")
8
+ .description("Merges a VIRTUAL-CODEOWNERS.txt and a virtual-teams.yml into CODEOWNERS")
7
9
  .version(VERSION)
8
- .arguments("<virtual-code-owners-file> <virtual-teams.yml>")
10
+ .option("-v, --virtual-code-owners [file-name]", "A CODEOWNERS file with team names in them that are defined in a virtual teams file", ".github/VIRTUAL-CODEOWNERS.txt")
11
+ .option("-t, --virtual-teams [file-name]", "A YAML file listing teams and their members", ".github/virtual-teams.yml")
12
+ .option("-c, --code-owners [file-name]", "The location of the CODEOWNERS file", ".github/CODEOWNERS")
9
13
  .parse(process.argv);
10
14
  try {
11
- console.log(readAndConvert(program.args[0], program.args[1]));
15
+ const lCodeOwnersContent = readAndConvert(program.opts().virtualCodeOwners, program.opts().virtualTeams);
16
+ writeFileSync(program.opts().codeOwners, lCodeOwnersContent, {
17
+ encoding: "utf-8",
18
+ });
19
+ console.error(`${EOL}Wrote ${program.opts().codeOwners}${EOL}`);
12
20
  }
13
21
  catch (pError) {
14
22
  console.error(`ERROR: ${pError.message}`);
23
+ process.exitCode = 1;
15
24
  }
@@ -4,13 +4,13 @@ const DEFAULT_GENERATED_WARNING = `#${EOL}` +
4
4
  `#${EOL}` +
5
5
  `# To make changes:${EOL}` +
6
6
  `#${EOL}` +
7
- `# - edit VIRTUAL-CODEOWNERS.txt${EOL}` +
8
- `# - run 'npx virtual-code-owners VIRTUAL-CODE-OWNERS.txt virtual-teams.yml > CODEOWNERS'${EOL}` +
7
+ `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
8
+ `# - run 'npx virtual-code-owners'${EOL}` +
9
9
  `#${EOL}${EOL}`;
10
10
  function replaceTeamNames(pLine, pTeamMap) {
11
11
  let lReturnValue = pLine;
12
12
  for (let lTeamName of Object.keys(pTeamMap)) {
13
- lReturnValue = lReturnValue.replace(`@${lTeamName}`, pTeamMap[lTeamName].map((pUserName) => `@${pUserName}`).join(" "));
13
+ lReturnValue = lReturnValue.replace(new RegExp(`(\\s)@${lTeamName}(\\s|$)`, "g"), `$1${pTeamMap[lTeamName].map((pUserName) => `@${pUserName}`).join(" ")}$2`);
14
14
  }
15
15
  return lReturnValue;
16
16
  }
@@ -25,9 +25,22 @@ function convertLine(pTeamMap) {
25
25
  }
26
26
  };
27
27
  }
28
+ function deduplicateUserNames(pLine) {
29
+ const lTrimmedLine = pLine.trim();
30
+ const lSplitLine = lTrimmedLine.match(/^(?<filesPattern>[^\s]+)(?<theRest>.*)$/);
31
+ if (lTrimmedLine.startsWith("#") || !lSplitLine?.groups) {
32
+ return pLine;
33
+ }
34
+ return `${lSplitLine.groups.filesPattern} ${Array.from(new Set(lSplitLine.groups.theRest.trim().split(/\s+/))).join(" ")}`;
35
+ }
36
+ function shouldAppearInResult(pLine) {
37
+ return !pLine.trimStart().startsWith("#!");
38
+ }
28
39
  export function convert(pCodeOwnersFileAsString, pTeamMap, pGeneratedWarning = DEFAULT_GENERATED_WARNING) {
29
40
  return `${pGeneratedWarning}${pCodeOwnersFileAsString
30
41
  .split(EOL)
42
+ .filter(shouldAppearInResult)
31
43
  .map(convertLine(pTeamMap))
44
+ .map(deduplicateUserNames)
32
45
  .join(EOL)}`;
33
46
  }
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.0.0";
1
+ export const VERSION = "2.1.0";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "virtual-code-owners",
3
- "version": "1.0.0",
4
- "description": "merges a VIRTUAL-CODEOWNERS.txt and a virtual-teams.yml into CODEOWNERS",
3
+ "version": "2.1.0",
4
+ "description": "Merges a VIRTUAL-CODEOWNERS.txt and a virtual-teams.yml into CODEOWNERS",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": [
@@ -16,21 +16,23 @@
16
16
  "files": [
17
17
  "dist",
18
18
  "package.json",
19
- "README.md"
19
+ "README.md",
20
+ "LICENSE"
20
21
  ],
21
22
  "scripts": {
22
- "build": "rm -rf dist && node tools/get-version.mjs > src/version.ts && tsc",
23
- "depcruise": "depcruise src --config .dependency-cruiser.cjs",
23
+ "build": "rm -rf dist && ts-node --esm tools/get-version.ts > src/version.ts && tsc",
24
+ "check": "npm run format && npm run build && npm run depcruise -- --no-progress && npm test",
25
+ "depcruise": "depcruise src tools --config .dependency-cruiser.cjs",
24
26
  "depcruise:graph": "depcruise src --include-only '^(src)' --config --output-type dot | dot -T svg | depcruise-wrap-stream-in-html > dependency-graph.html",
25
27
  "depcruise:graph:dev": "depcruise src --prefix vscode://file/$(pwd)/ --config --output-type dot | dot -T svg | depcruise-wrap-stream-in-html | browser",
26
28
  "depcruise:graph:diff:dev": "depcruise src --prefix vscode://file/$(pwd)/ --config --output-type dot --reaches \"$(watskeburt $SHA -T regex)\"| dot -T svg | depcruise-wrap-stream-in-html | browser",
27
- "depcruise:graph:diff:mermaid": "depcruise src --config --output-type mermaid --output-to - --reaches \"$(watskeburt $SHA -T regex)\"",
28
- "depcruise:html": "depcruise src --config --output-type err-html --output-to dependency-violation-report.html",
29
+ "depcruise:graph:diff:mermaid": "depcruise src tools --config --output-type mermaid --output-to - --reaches \"$(watskeburt $SHA -T regex)\"",
30
+ "depcruise:html": "depcruise src tools --config --output-type err-html --output-to dependency-violation-report.html",
29
31
  "format": "prettier --loglevel warn --write \"**/*.{md,ts,json,yml}\"",
32
+ "prepare": "husky install",
30
33
  "scm:stage": "git add .",
31
- "test": "NODE_OPTIONS=--no-warnings mocha",
32
- "test:cover": "NODE_OPTIONS=--no-warnings c8 mocha",
33
- "update-dependencies": "npm run upem:update && npm run upem:install && npm run format && npm run build && npm test",
34
+ "test": "NODE_OPTIONS=--no-warnings c8 mocha",
35
+ "update-dependencies": "npm run upem:update && npm run upem:install && npm run check",
34
36
  "upem-outdated": "npm outdated --json --long | upem --dry-run",
35
37
  "upem:install": "npm install",
36
38
  "upem:update": "npm outdated --json --long | upem | pbcopy && pbpaste",
@@ -51,9 +53,12 @@
51
53
  },
52
54
  "devDependencies": {
53
55
  "@types/js-yaml": "4.0.5",
54
- "@types/node": "18.14.5",
56
+ "@types/mocha": "10.0.1",
57
+ "@types/node": "18.14.6",
55
58
  "c8": "7.13.0",
56
59
  "dependency-cruiser": "12.10.0",
60
+ "husky": "8.0.3",
61
+ "lint-staged": "13.1.2",
57
62
  "mocha": "10.2.0",
58
63
  "prettier": "2.8.4",
59
64
  "ts-node": "10.9.1",