@toptal/davinci-monorepo 8.1.4-alpha-CRT-5891-create-coverage-command-082cae9e.3 → 8.1.4-alpha-CRT-5891-create-coverage-command-3ad3dcfd.4

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.
@@ -7,7 +7,7 @@ import { createGraphGenerateCommand } from '../src/commands/graph-generate.js'
7
7
  import metricsCommand from '../src/commands/metrics.js'
8
8
  // eslint-disable-next-line no-restricted-syntax
9
9
  import codeownersCommand from '../src/commands/codeowners/index.js'
10
- import { coverageCommand } from '../src/commands/coverage.js'
10
+ import { coverageCommand } from '../src/commands/coverage-command/index.js'
11
11
 
12
12
  cliEngine.loadCommands(
13
13
  [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/davinci-monorepo",
3
- "version": "8.1.4-alpha-CRT-5891-create-coverage-command-082cae9e.3+082cae9e",
3
+ "version": "8.1.4-alpha-CRT-5891-create-coverage-command-3ad3dcfd.4+3ad3dcfd",
4
4
  "description": "Monorepo utility tools",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -35,9 +35,10 @@
35
35
  "dependencies": {
36
36
  "@nodelib/fs.walk": "^1.2.6",
37
37
  "@oclif/core": "^1.16.1",
38
- "@toptal/davinci-cli-shared": "2.3.1-alpha-CRT-5891-create-coverage-command-082cae9e.35+082cae9e",
38
+ "@toptal/davinci-cli-shared": "2.3.1-alpha-CRT-5891-create-coverage-command-3ad3dcfd.36+3ad3dcfd",
39
39
  "chalk": "^4.1.2",
40
40
  "codeowners": "5.1.1",
41
+ "commander": "^10.0.0",
41
42
  "dependency-cruiser": "^12.5.0",
42
43
  "ervy": "^1.0.7",
43
44
  "execa": "^5.1.1",
@@ -54,5 +55,5 @@
54
55
  "devDependencies": {
55
56
  "@jest/globals": "^29.4.2"
56
57
  },
57
- "gitHead": "082cae9ecf302c878d2dcbe004d88ff1ba737381"
58
+ "gitHead": "3ad3dcfdfe83b96377701fd4b2534f7c209ca320"
58
59
  }
@@ -62,9 +62,6 @@ Codeowners.prototype.getOwner =
62
62
  * @param {string} filePath
63
63
  */
64
64
  function getOwner(filePath) {
65
- console.log({ filePath })
66
- console.log({ entries: this.ownerEntries })
67
-
68
65
  for (const entry of this.ownerEntries) {
69
66
  if (entry.match(filePath)) {
70
67
  return entry.usernames
@@ -0,0 +1,3 @@
1
+ export const JEST_COVERAGE_PATH = 'coverage/jest'
2
+ export const CYPRESS_COVERAGE_PATH = 'coverage/cypress'
3
+ export const TEAMS_COVERAGE_PATH = 'coverage/teams'
@@ -1,27 +1,26 @@
1
1
  import path from 'path'
2
- import * as url from 'url'
3
2
  import execa from 'execa'
4
3
  import fs from 'fs'
5
4
  import { print } from '@toptal/davinci-cli-shared'
6
5
  import getWorkspaceRoot from 'find-yarn-workspace-root'
7
6
 
8
- import Codeowners from './codeowners/core/codeowners/codeowners.js'
7
+ // eslint-disable-next-line no-restricted-syntax
8
+ import Codeowners from '../codeowners/core/codeowners/codeowners.js'
9
+ import { sanitizeTeamName } from './services/sanitize-team-name/sanitize-team-name.js'
10
+ import {
11
+ CYPRESS_COVERAGE_PATH,
12
+ JEST_COVERAGE_PATH,
13
+ TEAMS_COVERAGE_PATH,
14
+ } from './config.js'
9
15
 
10
- const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
11
- const rootProjectPath = path.join(__dirname, '../../')
12
16
  const workspaceRoot = getWorkspaceRoot()
13
17
 
14
- console.log('workspaceRoot', workspaceRoot)
15
- console.log('rootProjectPath', rootProjectPath)
16
-
17
- const sanitizeTeamName = team => team.replace('/', '-').replace('@', '')
18
-
19
18
  const sanitizeNycPercentage = percentage =>
20
19
  percentage === 'Unknown' ? 0 : percentage
21
20
 
22
21
  // eslint-disable-next-line max-statements
23
22
  const generateTeamCoverage = async options => {
24
- print.header('generateTeamCoverage')
23
+ print.header('Generating team coverage')
25
24
 
26
25
  const codeowners = new Codeowners(workspaceRoot)
27
26
 
@@ -31,43 +30,40 @@ const generateTeamCoverage = async options => {
31
30
  // eslint-disable-next-line id-length
32
31
  .filter((v, i, a) => a.indexOf(v) === i)
33
32
 
34
- // eslint-disable-next-line no-console
35
- console.log('Teams:', uniqueTeams)
33
+ print.grey('Teams: ', uniqueTeams)
36
34
 
37
35
  const teams = uniqueTeams
38
36
 
39
- await execa.command(`rm -rf coverage/teams`)
40
- await execa.command(`mkdir coverage/teams`)
37
+ await execa.command(`rm -rf ${TEAMS_COVERAGE_PATH}`)
38
+ await execa.command(`mkdir ${TEAMS_COVERAGE_PATH}`)
41
39
 
42
40
  for await (const team of teams) {
43
41
  const sanitizedTeam = sanitizeTeamName(team)
42
+ const sanitizedTeamPath = path.join(TEAMS_COVERAGE_PATH, sanitizedTeam)
44
43
 
45
- await execa.command(`mkdir coverage/teams/${sanitizedTeam}`)
46
- await execa.command(`mkdir coverage/teams/${sanitizedTeam}/jest`)
47
- await execa.command(`mkdir coverage/teams/${sanitizedTeam}/cypress`)
44
+ await execa.command(`mkdir ${sanitizedTeamPath}`)
45
+ await execa.command(`mkdir ${sanitizedTeamPath}/jest`)
46
+ await execa.command(`mkdir ${sanitizedTeamPath}/cypress`)
48
47
  }
49
48
 
50
49
  for await (const team of teams) {
51
- // eslint-disable-next-line no-console
52
- console.log('Team coverage:', team)
50
+ print.grey('Team coverage: ', team)
53
51
 
54
52
  const sanitizedTeam = sanitizeTeamName(team)
53
+ const sanitizedTeamPath = path.join(TEAMS_COVERAGE_PATH, sanitizedTeam)
55
54
 
56
55
  await execa.command(
57
- `cp coverage/jest/coverage-final-${sanitizedTeam}.json coverage/teams/${sanitizedTeam}/jest/coverage-final.json`
56
+ `cp ${JEST_COVERAGE_PATH}/coverage-final-${sanitizedTeam}.json ${sanitizedTeamPath}/jest/coverage-final.json`
58
57
  )
59
-
60
- // TODO add nyc as deps?
61
58
  await execa.command(
62
- `yarn nyc report --temp-dir coverage/teams/${sanitizedTeam}/jest --reporter json-summary --reporter html --report-dir coverage/teams/${sanitizedTeam}/jest`
59
+ `yarn nyc report --temp-dir ${sanitizedTeamPath}/jest --reporter json-summary --reporter html --report-dir ${sanitizedTeamPath}/jest`
63
60
  )
64
61
 
65
62
  await execa.command(
66
- `cp coverage/cypress/coverage-final-${sanitizedTeam}.json coverage/teams/${sanitizedTeam}/cypress/coverage-final.json`
63
+ `cp ${CYPRESS_COVERAGE_PATH}/coverage-final-${sanitizedTeam}.json ${sanitizedTeamPath}/cypress/coverage-final.json`
67
64
  )
68
-
69
65
  await execa.command(
70
- `yarn nyc report --temp-dir coverage/teams/${sanitizedTeam}/cypress --reporter json-summary --reporter html --report-dir coverage/teams/${sanitizedTeam}/cypress`
66
+ `yarn nyc report --temp-dir ${sanitizedTeamPath}/cypress --reporter json-summary --reporter html --report-dir ${sanitizedTeamPath}/cypress`
71
67
  )
72
68
  }
73
69
 
@@ -76,6 +72,8 @@ const generateTeamCoverage = async options => {
76
72
 
77
73
  for await (const team of teams) {
78
74
  const sanitizedTeam = sanitizeTeamName(team)
75
+ const sanitizedTeamPath = path.join(TEAMS_COVERAGE_PATH, sanitizedTeam)
76
+
79
77
  const result = {
80
78
  created_at,
81
79
  team,
@@ -83,10 +81,7 @@ const generateTeamCoverage = async options => {
83
81
  }
84
82
 
85
83
  const jestCoverageSummary = JSON.parse(
86
- fs.readFileSync(
87
- `coverage/teams/${sanitizedTeam}/jest/coverage-summary.json`,
88
- 'utf8'
89
- )
84
+ fs.readFileSync(`${sanitizedTeamPath}/jest/coverage-summary.json`, 'utf8')
90
85
  )
91
86
 
92
87
  result.jest_lines_coverage = sanitizeNycPercentage(
@@ -104,7 +99,7 @@ const generateTeamCoverage = async options => {
104
99
 
105
100
  const cypressCoverageSummary = JSON.parse(
106
101
  fs.readFileSync(
107
- `coverage/teams/${sanitizedTeam}/cypress/coverage-summary.json`,
102
+ `${sanitizedTeamPath}/cypress/coverage-summary.json`,
108
103
  'utf8'
109
104
  )
110
105
  )
@@ -125,21 +120,19 @@ const generateTeamCoverage = async options => {
125
120
  results.push(result)
126
121
  }
127
122
 
128
- fs.writeFileSync(
129
- 'team-tests-coverage-results.json',
130
- JSON.stringify(results, null, 2)
131
- )
123
+ fs.writeFileSync(options.outputFileName, JSON.stringify(results, null, 2))
132
124
  }
133
125
 
134
- export const generateTeamCoverageCommand = program => {
135
- print.header('generateTeamCoverageCommand')
136
-
137
- return program
126
+ export const generateTeamCoverageCommand = program =>
127
+ program
138
128
  .command('generate-team-coverage')
139
129
  .description('TODO: generate-team-coverage')
140
130
  .requiredOption(
141
131
  '-r, --repository <repository_name>',
142
132
  'specify repository name'
143
133
  )
144
- .action(options => generateTeamCoverage(options))
145
- }
134
+ .requiredOption(
135
+ '-o, --output-file-name <output_file_name>',
136
+ 'specify output file name'
137
+ )
138
+ .action(generateTeamCoverage)
@@ -1,22 +1,20 @@
1
1
  import path from 'path'
2
2
  import fs from 'fs'
3
- import * as url from 'url'
4
3
  import { print } from '@toptal/davinci-cli-shared'
5
4
  import getWorkspaceRoot from 'find-yarn-workspace-root'
6
5
 
7
- import Codeowners from './codeowners/core/codeowners/codeowners.js'
6
+ // eslint-disable-next-line no-restricted-syntax
7
+ import Codeowners from '../codeowners/core/codeowners/codeowners.js'
8
+ import { CYPRESS_COVERAGE_PATH, JEST_COVERAGE_PATH } from './config.js'
9
+ import { sanitizeTeamName } from './services/sanitize-team-name/sanitize-team-name.js'
8
10
 
9
- const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
10
- const rootProjectPath = path.join(__dirname, '../../')
11
11
  const workspaceRoot = getWorkspaceRoot()
12
12
 
13
- console.log('workspaceRoot', workspaceRoot)
14
- console.log('rootProjectPath', rootProjectPath)
15
-
16
13
  const readJestCoverageReport = () => {
17
14
  const jestCoverageReportPath = path.join(
18
15
  workspaceRoot,
19
- 'coverage/jest/coverage-final-jest.json'
16
+ JEST_COVERAGE_PATH,
17
+ 'coverage-final-jest.json'
20
18
  )
21
19
 
22
20
  const data = fs.readFileSync(jestCoverageReportPath, 'utf8')
@@ -27,7 +25,8 @@ const readJestCoverageReport = () => {
27
25
  const readCypressCoverageReport = () => {
28
26
  const cypressCoverageReportPath = path.join(
29
27
  workspaceRoot,
30
- 'coverage/cypress/coverage-final-cypress.json'
28
+ CYPRESS_COVERAGE_PATH,
29
+ 'coverage-final-cypress.json'
31
30
  )
32
31
 
33
32
  const data = fs.readFileSync(cypressCoverageReportPath, 'utf8')
@@ -35,19 +34,18 @@ const readCypressCoverageReport = () => {
35
34
  return JSON.parse(data)
36
35
  }
37
36
 
38
- const sanitizeTeamName = team => team.replace('/', '-').replace('@', '')
39
-
40
- const splitReportIntoTeams = (reportObj, teams, codeowners, coveragePath) => {
37
+ const splitReportIntoTeams = ({
38
+ reportObj,
39
+ teams,
40
+ codeowners,
41
+ coveragePath,
42
+ }) => {
41
43
  const teamsReport = {}
42
44
 
43
45
  Object.entries(reportObj).forEach(([reportPathKey, report]) => {
44
46
  const file = report.path
45
- const relativePath = path.relative(rootProjectPath, file)
46
47
  const relativeWorkspacePath = path.relative(workspaceRoot, file)
47
48
 
48
- console.log('relativePath', relativePath)
49
- console.log('relativeWorkspacePath', relativeWorkspacePath)
50
-
51
49
  const owners = codeowners.getOwner(relativeWorkspacePath)
52
50
 
53
51
  owners.forEach(owner => {
@@ -64,7 +62,8 @@ const splitReportIntoTeams = (reportObj, teams, codeowners, coveragePath) => {
64
62
 
65
63
  const reportPath = path.join(
66
64
  workspaceRoot,
67
- `${coveragePath}/coverage-final-${sanitizedTeamPath}.json`
65
+ coveragePath,
66
+ `coverage-final-${sanitizedTeamPath}.json`
68
67
  )
69
68
 
70
69
  fs.writeFileSync(reportPath, JSON.stringify(teamReport, null, 2))
@@ -78,14 +77,13 @@ const getAllTeams = codeowners => {
78
77
  // eslint-disable-next-line id-length
79
78
  .filter((v, i, a) => a.indexOf(v) === i)
80
79
 
81
- // eslint-disable-next-line no-console
82
- console.log('Teams:', uniqueTeams)
80
+ print.grey('Teams: ', uniqueTeams)
83
81
 
84
82
  return uniqueTeams
85
83
  }
86
84
 
87
85
  const groupCoverageByCodeowners = async () => {
88
- print.header('groupCoverageByCodeowners')
86
+ print.header('Grouping coverage by codeowners')
89
87
 
90
88
  const jestReport = readJestCoverageReport()
91
89
  const cypressReport = readCypressCoverageReport()
@@ -93,15 +91,22 @@ const groupCoverageByCodeowners = async () => {
93
91
  const codeowners = new Codeowners(workspaceRoot)
94
92
  const teams = getAllTeams(codeowners)
95
93
 
96
- splitReportIntoTeams(jestReport, teams, codeowners, 'coverage/jest')
97
- splitReportIntoTeams(cypressReport, teams, codeowners, 'coverage/cypress')
94
+ splitReportIntoTeams({
95
+ report: jestReport,
96
+ teams,
97
+ codeowners,
98
+ coveragePath: JEST_COVERAGE_PATH,
99
+ })
100
+ splitReportIntoTeams({
101
+ report: cypressReport,
102
+ teams,
103
+ codeowners,
104
+ coveragePath: CYPRESS_COVERAGE_PATH,
105
+ })
98
106
  }
99
107
 
100
- export const groupCoverageByCodeownersCommand = program => {
101
- print.header('groupCoverageByCodeownersCommand')
102
-
103
- return program
108
+ export const groupCoverageByCodeownersCommand = program =>
109
+ program
104
110
  .command('group-coverage-by-codeowners')
105
111
  .description('TODO: group-coverage-by-codeowners')
106
112
  .action(groupCoverageByCodeowners)
107
- }
@@ -0,0 +1 @@
1
+ export const sanitizeTeamName = team => team.replace('/', '-').replace('@', '')
package/src/index.js CHANGED
@@ -2,7 +2,7 @@ import detectCircularityCommandCreator from './commands/detect-circularity.js'
2
2
  import metricsCommandCreator from './commands/metrics.js'
3
3
  import { createGraphGenerateCommand } from './commands/graph-generate.js'
4
4
  import codeownersCommand from './commands/codeowners/index.js'
5
- import { coverageCommand } from './commands/coverage.js'
5
+ import { coverageCommand } from './commands/coverage-command/index.js'
6
6
  import checkIfMonorepo from './utils/check-if-monorepo.js'
7
7
  import getPackages from './utils/get-packages.js'
8
8