virtual-code-owners 2.1.0 → 2.2.1

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
@@ -22,8 +22,8 @@ or, if you want to be verbose
22
22
  ```
23
23
  npx virtual-code-owners \
24
24
  --virtual-code-owners .github/VIRTUAL-CODEOWNERS.txt \
25
- --virtual-teams .github/virtual-teams.yml \
26
- --code-owners .github/CODEOWNERS
25
+ --virtual-teams .github/virtual-teams.yml \
26
+ --code-owners .github/CODEOWNERS
27
27
  ```
28
28
 
29
29
  ## Why?
@@ -38,59 +38,114 @@ have the following choices:
38
38
  though there are good people on many levels in bureaucracies, it might
39
39
  eventually not pan out because #reasons.
40
40
  - Maintain a CODEOWNERS file with code assigned to large lists of individuals.
41
- An option, but laborious to maintain.
42
- - Use `virtual-code-owners`.
41
+ An option, but laborious to maintain, even for smaller projects; for example:
42
+
43
+ ```CODEOWNERS
44
+ # catch-all to ensure there at least _is_ a code owner, even when
45
+ # it's _everyone_
46
+
47
+ * @cloud-heroes-all
48
+
49
+ # admin & ci stuff => transversal
50
+
51
+ .github/ @abraham-lincoln @benjamin-franklin @koos-koets @luke-the-lucky-ch @mary-the-merry-ch @naomi-the-namegiver-ch
52
+
53
+ # generic stuff
54
+
55
+ apps/framework/ @abraham-lincoln @benjamin-franklin @koos-koets @luke-the-lucky-ch @mary-the-merry-ch @naomi-the-namegiver-ch
56
+ apps/ux-portal/ @abraham-lincoln @benjamin-franklin @charlotte-de-bourbon-ch @davy-davidson-ch @joe-dalton-ch @john-johnson-ch @koos-koets @luke-the-lucky-ch @mary-the-merry-ch @naomi-the-namegiver-ch
57
+ libs/components/ @charlotte-de-bourbon-ch @davy-davidson-ch @joe-dalton-ch @john-johnson-ch @koos-koets
58
+
59
+ # specific functionality
60
+
61
+ libs/ubc-sales/ @abraham-ableton-ch @boris-bubbleblower-ch @charlotte-charleston-ch @dagny-taggert-ch @gregory-gregson-ch @jane-doe-ch @karl-marx-ch
62
+ libs/ubc-after-sales/ @daisy-duck @donald-duck @john-doe-ch @pete-peterson-ch @william-the-fourth-ch
63
+ libs/ubc-pre-sales/ @averel-dalton-ch @jean-claude-ch @john-galt-ch @valerie-valerton-ch
64
+ libs/ubc-refund/ @abraham-ableton-ch @boris-bubbleblower-ch @charlotte-charleston-ch @dagny-taggert-ch @daisy-duck @donald-duck @gregory-gregson-ch @jane-doe-ch @john-doe-ch @karl-marx-ch @pete-peterson-ch @william-the-fourth-ch
65
+ ```
66
+
67
+ This is where `virtual-code-owners` comes in.
43
68
 
44
69
  ## Formats
45
70
 
46
71
  ### VIRTUAL-CODEOWNERS.txt
47
72
 
48
- `VIRTUAL_CODEOWNERS.txt` is a regular, valid GitHub [CODEOWNERS](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-and-branch-protection) file.
49
- The only difference between VIRTUAL-CODEOWNERS and a CODEOWNERS file is that
73
+ `VIRTUAL_CODEOWNERS.txt` is a regular, valid GitHub [CODEOWNERS](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners) file.
74
+ The only difference between VIRTUAL-CODEOWNERS.txt and a CODEOWNERS file is that
50
75
  the _teams_ the former uses might not exist yet, except in a `virtual-teams.yml`.
76
+ This enables you to write a _much_ easier to maintain list of code owners.
51
77
 
52
- Example:
78
+ For example the CODEOWNERS file above can then look like this:
53
79
 
54
- ```
55
- #! comments that start with #! won't appear in the CODEOWNERS output e.g.
80
+ ```CODEOWNERS
81
+ #! comments that start with #! won't appear in the CODEOWNERS output
82
+ #!
56
83
  #! 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.
84
+ #! npx virtual-code-owners
59
85
  #!
60
- # Regular comments are retained
86
+ # catch-all to ensure there at least _is_ a code owner, even when
87
+ # it's _everyone_
88
+
61
89
  * @cloud-heroes-all
62
- .github/ @ch/transversal
63
- apps/broker @ch/transversal
64
- apps/ux-portal/ @ch/ux @ch/transversal
65
- libs/ubc-sales/ @ch/sales
66
- libs/ubc-after-sales/ @ch/after-sales
67
- libs/ubc-pre-sales/ @ch/pre-sales
68
- libs/components/ @ch/ux
90
+
91
+ # admin & ci stuff => transversal
92
+
93
+ .github/ @ch/transversal
94
+
95
+ # generic stuff
96
+
97
+ apps/framework/ @ch/transversal
98
+ apps/ux-portal/ @ch/ux @ch/transversal
99
+ libs/components/ @ch/ux
100
+
101
+ # specific functionality
102
+
103
+ libs/ubc-sales/ @ch/sales
104
+ libs/ubc-after-sales/ @ch/after-sales
105
+ libs/ubc-pre-sales/ @ch/pre-sales
106
+ libs/ubc-refund/ @ch/sales @ch/after-sales
69
107
  ```
70
108
 
71
109
  ### virtual-teams.yml
72
110
 
73
- A valid YAML file that contains a list of teams, with for each team its members:
111
+ A valid YAML file that contains a list of teams, with for each team its members.
112
+ If a new team member joins, you can enter it here, run `npx virtual-code-owners`
113
+ to update CODEOWNERS.
74
114
 
75
115
  ```yaml
116
+ # yaml-language-server: $schema=https://raw.githubusercontent.com/sverweij/virtual-code-owners/main/src/virtual-teams.schema.json
76
117
  ch/after-sales:
77
118
  - john-doe-ch
78
119
  - pete-peterson-ch
79
120
  - william-the-fourth-ch
121
+ - daisy-duck
122
+ - donald-duck
80
123
  ch/sales:
81
124
  - gregory-gregson-ch
82
125
  - jane-doe-ch
126
+ - abraham-ableton-ch
127
+ - boris-bubbleblower-ch
128
+ - charlotte-charleston-ch
129
+ - dagny-taggert-ch
130
+ - karl-marx-ch
83
131
  ch/pre-sales:
84
132
  - jean-claude-ch
85
133
  - valerie-valerton-ch
86
134
  - averel-dalton-ch
135
+ - john-galt-ch
87
136
  ch/ux:
88
137
  - davy-davidson-ch
89
138
  - john-johnson-ch
90
139
  - joe-dalton-ch
140
+ - koos-koets
141
+ - charlotte-de-bourbon-ch
91
142
  ch/transversal:
143
+ - mary-the-merry-ch
92
144
  - luke-the-lucky-ch
93
- # etc
145
+ - naomi-the-namegiver-ch
146
+ - benjamin-franklin
147
+ - koos-koets
148
+ - abraham-lincoln
94
149
  ```
95
150
 
96
151
  ## FAQ
@@ -114,14 +169,10 @@ team name and _virtual-code-owners_ will leave the real name alone.
114
169
 
115
170
  - Currently only works for _usernames_ to identify team members - not for e-mail
116
171
  addresses.
117
- - If people are in more than one team, chances are they get mentioned multiple
118
- times on the same line if both teams are code owners of the same part of the
119
- code. While maybe not _looking_ ideal, the resulting code owners file is still
120
- valid & ready to rock'n roll.
121
172
  - _virtual-code-owners_ assumes the VIRTUAL-CODEOWNERS.txt is a valid CODEOWNERS
122
173
  file and the virtual-teams.yml is a valid yaml file with teams names as keys
123
174
  and team members as arrays under these. It will likely throw errors when this
124
- assumption is not met, but the error-messages might not be as clear as possible.
175
+ assumption is not met, but the error-messages might be cryptic.
125
176
 
126
177
  ### Why the `.txt` extension?
127
178
 
@@ -1,46 +1,49 @@
1
1
  import { EOL } from "node:os";
2
- const DEFAULT_GENERATED_WARNING = `#${EOL}` +
2
+ const DEFAULT_WARNING = `#${EOL}` +
3
3
  `# DO NOT EDIT - this file is generated and your edits will be overwritten${EOL}` +
4
4
  `#${EOL}` +
5
5
  `# To make changes:${EOL}` +
6
6
  `#${EOL}` +
7
7
  `# - edit .github/VIRTUAL-CODEOWNERS.txt${EOL}` +
8
+ `# - and/ or add team members to .github/virtual-teams.yml${EOL}` +
8
9
  `# - run 'npx virtual-code-owners'${EOL}` +
9
10
  `#${EOL}${EOL}`;
10
- function replaceTeamNames(pLine, pTeamMap) {
11
- let lReturnValue = pLine;
12
- for (let lTeamName of Object.keys(pTeamMap)) {
13
- lReturnValue = lReturnValue.replace(new RegExp(`(\\s)@${lTeamName}(\\s|$)`, "g"), `$1${pTeamMap[lTeamName].map((pUserName) => `@${pUserName}`).join(" ")}$2`);
14
- }
15
- return lReturnValue;
11
+ export function convert(pCodeOwnersFileAsString, pTeamMap, pGeneratedWarning = DEFAULT_WARNING) {
12
+ return (pGeneratedWarning +
13
+ pCodeOwnersFileAsString
14
+ .split(EOL)
15
+ .filter(shouldAppearInResult)
16
+ .map(convertLine(pTeamMap))
17
+ .join(EOL));
18
+ }
19
+ function shouldAppearInResult(pLine) {
20
+ return !pLine.trimStart().startsWith("#!");
16
21
  }
17
22
  function convertLine(pTeamMap) {
18
23
  return (pUntreatedLine) => {
19
- const lTrimmedLine = pUntreatedLine.trimStart();
20
- if (lTrimmedLine.startsWith("#") || lTrimmedLine === "") {
24
+ const lTrimmedLine = pUntreatedLine.trim();
25
+ const lSplitLine = lTrimmedLine.match(/^(?<filesPattern>[^\s]+\s+)(?<userNames>.*)$/);
26
+ if (lTrimmedLine.startsWith("#") ||
27
+ lTrimmedLine === "" ||
28
+ !lSplitLine?.groups) {
21
29
  return pUntreatedLine;
22
30
  }
23
- else {
24
- return replaceTeamNames(pUntreatedLine, pTeamMap);
25
- }
31
+ const lUserNames = replaceTeamNames(lSplitLine.groups.userNames, pTeamMap);
32
+ return lSplitLine.groups.filesPattern + uniqAndSortUserNames(lUserNames);
26
33
  };
27
34
  }
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;
35
+ function replaceTeamNames(pUserNames, pTeamMap) {
36
+ let lReturnValue = pUserNames;
37
+ for (let lTeamName of Object.keys(pTeamMap)) {
38
+ lReturnValue = lReturnValue.replace(new RegExp(`(\\s|^)@${lTeamName}(\\s|$)`, "g"), `$1${stringifyTeamMembers(pTeamMap, lTeamName)}$2`);
33
39
  }
34
- return `${lSplitLine.groups.filesPattern} ${Array.from(new Set(lSplitLine.groups.theRest.trim().split(/\s+/))).join(" ")}`;
40
+ return lReturnValue;
35
41
  }
36
- function shouldAppearInResult(pLine) {
37
- return !pLine.trimStart().startsWith("#!");
42
+ function stringifyTeamMembers(pTeamMap, pTeamName) {
43
+ return pTeamMap[pTeamName].map((pUserName) => `@${pUserName}`).join(" ");
38
44
  }
39
- export function convert(pCodeOwnersFileAsString, pTeamMap, pGeneratedWarning = DEFAULT_GENERATED_WARNING) {
40
- return `${pGeneratedWarning}${pCodeOwnersFileAsString
41
- .split(EOL)
42
- .filter(shouldAppearInResult)
43
- .map(convertLine(pTeamMap))
44
- .map(deduplicateUserNames)
45
- .join(EOL)}`;
45
+ function uniqAndSortUserNames(pUserNames) {
46
+ return Array.from(new Set(pUserNames.split(/\s+/)))
47
+ .sort()
48
+ .join(" ");
46
49
  }
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "2.1.0";
1
+ export const VERSION = "2.2.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-code-owners",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "Merges a VIRTUAL-CODEOWNERS.txt and a virtual-teams.yml into CODEOWNERS",
5
5
  "type": "module",
6
6
  "exports": {
@@ -54,17 +54,17 @@
54
54
  "devDependencies": {
55
55
  "@types/js-yaml": "4.0.5",
56
56
  "@types/mocha": "10.0.1",
57
- "@types/node": "18.14.6",
57
+ "@types/node": "18.15.3",
58
58
  "c8": "7.13.0",
59
- "dependency-cruiser": "12.10.0",
59
+ "dependency-cruiser": "12.11.0",
60
60
  "husky": "8.0.3",
61
- "lint-staged": "13.1.2",
61
+ "lint-staged": "13.2.0",
62
62
  "mocha": "10.2.0",
63
63
  "prettier": "2.8.4",
64
64
  "ts-node": "10.9.1",
65
- "typescript": "4.9.5",
65
+ "typescript": "5.0.2",
66
66
  "upem": "7.3.2",
67
- "watskeburt": "0.10.0"
67
+ "watskeburt": "0.10.1"
68
68
  },
69
69
  "dependencies": {
70
70
  "commander": "10.0.0",