@jsenv/lighthouse-impact 1.2.1 → 2.1.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/README.md CHANGED
@@ -1,12 +1,4 @@
1
- # Lighthouse impact
2
-
3
- Report pull request impacts on lighthouse score.
4
-
5
- [![npm package](https://img.shields.io/npm/v/@jsenv/lighthouse-impact.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/lighthouse-impact)
6
- [![github main](https://github.com/jsenv/lighthouse-impact/workflows/main/badge.svg)](https://github.com/jsenv/lighthouse-impact/actions?workflow=main)
7
- [![codecov coverage](https://codecov.io/gh/jsenv/lighthouse-impact/branch/main/graph/badge.svg)](https://codecov.io/gh/jsenv/lighthouse-impact)
8
-
9
- # Presentation
1
+ # Lighthouse impact [![npm package](https://img.shields.io/npm/v/@jsenv/lighthouse-impact.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/lighthouse-impact) [![github main](https://github.com/jsenv/lighthouse-impact/workflows/main/badge.svg)](https://github.com/jsenv/lighthouse-impact/actions?workflow=main) [![codecov coverage](https://codecov.io/gh/jsenv/lighthouse-impact/branch/main/graph/badge.svg)](https://codecov.io/gh/jsenv/lighthouse-impact)
10
2
 
11
3
  `@jsenv/lighthouse-impact` analyses a pull request impact on lighthouse score. This analysis is posted in a comment of the pull request on GitHub.
12
4
 
@@ -32,7 +24,7 @@ The first thing you need is a script capable to generate a lighthouse report.
32
24
  npm install --save-dev @jsenv/lighthouse-impact
33
25
  ```
34
26
 
35
- _generate_lighthouse_report.mjs_
27
+ _lighthouse.mjs_
36
28
 
37
29
  ```js
38
30
  /*
@@ -42,24 +34,23 @@ _generate_lighthouse_report.mjs_
42
34
  */
43
35
  import { createServer } from "node:http"
44
36
  import { readFileSync } from "node:fs"
45
- import { getLighthouseReportUsingHeadlessChrome } from "@jsenv/lighthouse-impact"
37
+ import { generateLighthouseReport } from "@jsenv/lighthouse-impact"
46
38
 
47
39
  const htmlFileUrl = new URL("./index.html", import.meta.url)
48
40
  const html = String(readFileSync(htmlFileUrl))
49
41
 
50
- export const generateLighthouseReport = async () => {
51
- const server = createServer((request, response) => {
52
- response.writeHead(200, {
53
- "content-type": "text/html",
54
- })
55
- response.end(html)
42
+ const server = createServer((request, response) => {
43
+ response.writeHead(200, {
44
+ "content-type": "text/html",
56
45
  })
57
- server.listen(8080)
58
- server.unref()
46
+ response.end(html)
47
+ })
48
+ server.listen(8080)
49
+ server.unref()
59
50
 
60
- const lighthouseReport = await getLighthouseReportUsingHeadlessChrome("http://127.0.0.1:8080")
61
- return lighthouseReport
62
- }
51
+ export const lighthouseReport = await generateLighthouseReport(
52
+ "http://127.0.0.1:8080",
53
+ )
63
54
  ```
64
55
 
65
56
  _index.html_
@@ -78,7 +69,7 @@ _index.html_
78
69
  </html>
79
70
  ```
80
71
 
81
- At this stage, you could generate a lighthouse report on your machine. For an example, see [package.json#L36](./package.json#L36) and [script/lighthouse/generate_lighthouse_report.mjs#L35](./script/lighthouse/generate_lighthouse_report.mjs#L35).
72
+ At this stage, you could generate a lighthouse report on your machine. For an example, see [package.json#L37](./package.json#L37) and [script/lighthouse/lighthouse.mjs#L19](./script/lighthouse/lighthouse.mjs#L19).
82
73
 
83
74
  Now it's time to configure a workflow to compare lighthouse reports before and after merging a pull request.
84
75
 
@@ -108,10 +99,10 @@ jobs:
108
99
  - name: Setup git
109
100
  uses: actions/checkout@v2
110
101
  - name: Setup node
111
- uses: actions/setup-node@v1
102
+ uses: actions/setup-node@v2
112
103
  with:
113
- node-version: "16.x"
114
- - name: Setup npm
104
+ node-version: "16.13.0"
105
+ - name: Install node modules
115
106
  run: npm install
116
107
  - name: Report lighthouse impact
117
108
  run: node ./report_lighthouse_impact.mjs
@@ -127,11 +118,14 @@ _report_lighthouse_impact.mjs_
127
118
  * See https://github.com/jsenv/lighthouse-impact#how-it-works
128
119
  */
129
120
 
130
- import { reportLighthouseImpact, readGitHubWorkflowEnv } from "@jsenv/lighthouse-impact"
121
+ import {
122
+ reportLighthouseImpact,
123
+ readGitHubWorkflowEnv,
124
+ } from "@jsenv/lighthouse-impact"
131
125
 
132
- reportLighthouseImpact({
126
+ await reportLighthouseImpact({
133
127
  ...readGitHubWorkflowEnv(),
134
- moduleGeneratingLighthouseReportRelativeUrl: "./generate_lighthouse_report.mjs",
128
+ lighthouseReportPath: "./lighthouse.mjs#lighthouseReport",
135
129
  })
136
130
  ```
137
131
 
@@ -173,7 +167,7 @@ reportLighthouseImpact({
173
167
  + repositoryName: process.env.TRAVIS_REPO_SLUG.split("/")[1],
174
168
  + pullRequestNumber: process.env.TRAVIS_PULL_REQUEST,
175
169
  + githubToken: process.env.GITHUB_TOKEN, // see next step
176
- moduleGeneratingLighthouseReportRelativeUrl: "./generate_lighthouse_report.mjs",
170
+ lighthouseReportPath: "./lighthouse.mjs#lighthouseReport",
177
171
  })
178
172
  ```
179
173
 
package/main.js CHANGED
@@ -1,5 +1,4 @@
1
- export { readGitHubWorkflowEnv } from "@jsenv/github-pull-request-impact"
1
+ export { generateLighthouseReport } from "./src/generateLighthouseReport.js"
2
2
 
3
- export { getLighthouseReportUsingHeadlessChrome } from "./src/getLighthouseReportUsingHeadlessChrome.js"
4
- export { logLighthouseReport } from "./src/logLighthouseReport.js"
3
+ export { readGitHubWorkflowEnv } from "@jsenv/github-pull-request-impact"
5
4
  export { reportLighthouseImpact } from "./src/reportLighthouseImpact.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/lighthouse-impact",
3
- "version": "1.2.1",
3
+ "version": "2.1.2",
4
4
  "description": "Package description",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -13,7 +13,7 @@
13
13
  "url": "https://github.com/jsenv/lighthouse-impact"
14
14
  },
15
15
  "engines": {
16
- "node": ">=14.17.0"
16
+ "node": ">=16.13.0"
17
17
  },
18
18
  "publishConfig": {
19
19
  "access": "public",
@@ -26,47 +26,43 @@
26
26
  },
27
27
  "./*": "./*"
28
28
  },
29
+ "main": "./main.js",
29
30
  "files": [
30
31
  "/src/",
31
32
  "/main.js"
32
33
  ],
33
34
  "scripts": {
34
- "eslint-check": "node ./node_modules/eslint/bin/eslint.js .",
35
- "generate-importmap": "node ./script/importmap/generate_importmap.mjs",
36
- "measure-performances": "node ./script/performance/generate_performance_report.mjs --local",
37
- "generate-lighthouse-report": "node ./script/lighthouse/generate_lighthouse_report.mjs --local",
35
+ "eslint": "node ./node_modules/eslint/bin/eslint.js . --ext=.js,.mjs",
36
+ "importmap": "node ./script/importmap/importmap.mjs",
37
+ "performance": "node --expose-gc ./script/performance/performance.mjs --log",
38
+ "lighthouse": "node ./script/lighthouse/lighthouse.mjs --local",
38
39
  "generate-comment-snapshot-file": "node ./test/comment/generate_comment_snapshot_file.mjs",
39
40
  "test": "node ./script/test/test.mjs",
40
41
  "test-with-coverage": "npm run test -- --coverage",
41
- "prettier-format": "node ./script/prettier/prettier_format.mjs",
42
- "prettier-format-stage": "npm run prettier-format -- --staged",
43
- "prettier-check": "npm run prettier-format -- --dry-run",
44
- "prepublishOnly": "node ./script/publish/remove_postinstall.mjs",
45
- "postpublish": "node ./script/publish/restore_postinstall.mjs"
42
+ "prettier": "prettier --write ."
46
43
  },
47
44
  "dependencies": {
48
- "@jsenv/cancellation": "3.0.0",
45
+ "@jsenv/abort": "4.1.2",
46
+ "@jsenv/dynamic-import-worker": "1.0.0",
47
+ "@jsenv/filesystem": "2.5.1",
49
48
  "@jsenv/github-pull-request-impact": "1.6.4",
50
49
  "@jsenv/logger": "4.0.1",
51
- "@jsenv/util": "4.1.1",
52
- "chrome-launcher": "0.14.0",
53
- "lighthouse": "8.2.0"
50
+ "chrome-launcher": "0.15.0",
51
+ "lighthouse": "9.1.0"
54
52
  },
55
53
  "devDependencies": {
56
- "@jsenv/assert": "2.2.6",
57
- "@jsenv/codecov-upload": "3.5.0",
58
- "@jsenv/core": "19.6.2",
59
- "@jsenv/eslint-config": "15.0.2",
54
+ "@jsenv/assert": "2.4.0",
55
+ "@jsenv/core": "24.5.8",
56
+ "@jsenv/eslint-config": "16.0.9",
60
57
  "@jsenv/github-release-package": "1.2.3",
61
- "@jsenv/importmap-eslint-resolver": "5.1.0",
62
- "@jsenv/importmap-node-module": "1.0.1",
58
+ "@jsenv/importmap-eslint-resolver": "5.2.1",
59
+ "@jsenv/importmap-node-module": "2.8.0",
63
60
  "@jsenv/package-publish": "1.6.2",
64
- "@jsenv/performance-impact": "1.6.2",
65
- "@jsenv/prettier-check-project": "5.6.1",
66
- "@jsenv/server": "6.1.1",
67
- "eslint": "7.32.0",
68
- "eslint-plugin-html": "6.1.2",
69
- "eslint-plugin-import": "2.24.0",
70
- "prettier": "2.3.2"
61
+ "@jsenv/performance-impact": "2.2.1",
62
+ "@jsenv/server": "12.2.0",
63
+ "eslint": "8.4.1",
64
+ "eslint-plugin-html": "6.2.0",
65
+ "eslint-plugin-import": "2.25.3",
66
+ "prettier": "2.5.1"
71
67
  }
72
68
  }
@@ -3,30 +3,24 @@
3
3
  import { createRequire } from "node:module"
4
4
 
5
5
  import { createLogger } from "@jsenv/logger"
6
+ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
7
+
6
8
  import {
7
- createCancellationToken,
8
- createCancellationSource,
9
- composeCancellationToken,
10
- createOperation,
11
- executeAsyncFunction,
12
- } from "@jsenv/cancellation"
13
- import { writeFile, resolveUrl } from "@jsenv/util"
9
+ writeFile,
10
+ resolveUrl,
11
+ assertAndNormalizeDirectoryUrl,
12
+ } from "@jsenv/filesystem"
14
13
 
15
- const require = createRequire(import.meta.url)
14
+ import { formatLighthouseReportForLog } from "./internal/formatLighthouseReportForLog.js"
16
15
 
17
- const lighthouse = require("lighthouse")
18
- // eslint-disable-next-line import/no-unresolved
19
- const ReportGenerator = require("lighthouse/report/report-generator")
20
- const { computeMedianRun } = require("lighthouse/lighthouse-core/lib/median-run.js")
21
- const chromeLauncher = require("chrome-launcher")
16
+ const require = createRequire(import.meta.url)
22
17
 
23
- export const getLighthouseReportUsingHeadlessChrome = async (
18
+ export const generateLighthouseReport = async (
24
19
  url,
25
20
  {
26
- cancellationToken = createCancellationToken(),
27
- cancelOnSIGINT = true,
21
+ signal = new AbortController().signal,
22
+ handleSIGINT = true,
28
23
  logLevel,
29
- projectDirectoryUrl,
30
24
 
31
25
  headless = true,
32
26
  gpu = false,
@@ -38,29 +32,33 @@ export const getLighthouseReportUsingHeadlessChrome = async (
38
32
  runCount = 1,
39
33
  delayBetweenEachRunInSeconds = 1,
40
34
 
41
- jsonFile = Boolean(projectDirectoryUrl),
35
+ projectDirectoryUrl, // required only when jsonFile or htmlFile is passed
36
+ log = false,
37
+ jsonFile = false,
42
38
  jsonFileRelativeUrl = "./lighthouse/lighthouse_report.json",
43
39
  jsonFileLog = true,
44
- htmlFile = Boolean(projectDirectoryUrl),
40
+ htmlFile = false,
45
41
  htmlFileRelativeUrl = "./lighthouse/lighthouse_report.html",
46
42
  htmlFileLog = true,
47
43
  } = {},
48
44
  ) => {
49
- let cleanup = () => {}
50
-
51
- if (cancelOnSIGINT) {
52
- const processCancellationSource = createCancellationSource()
53
- const processCancellationToken = processCancellationSource.token
54
- cancellationToken = composeCancellationToken(cancellationToken, processCancellationToken)
55
- const SIGINTCallback = () => {
56
- processCancellationSource.cancel("process SIGINT")
57
- }
58
- process.once("SIGINT", SIGINTCallback)
59
- // beware if someday something do things on cleanup
60
- // to call the old cleanup function
61
- cleanup = () => {
62
- process.removeListener("SIGINT", SIGINTCallback)
63
- }
45
+ const ReportGenerator = require("lighthouse/report/generator/report-generator.js")
46
+ const {
47
+ computeMedianRun,
48
+ } = require("lighthouse/lighthouse-core/lib/median-run.js")
49
+ const chromeLauncher = require("chrome-launcher")
50
+
51
+ const generateReportOperation = Abort.startOperation()
52
+ generateReportOperation.addAbortSignal(signal)
53
+ if (handleSIGINT) {
54
+ generateReportOperation.addAbortSource((abort) => {
55
+ return raceProcessTeardownEvents(
56
+ {
57
+ SIGINT: true,
58
+ },
59
+ abort,
60
+ )
61
+ })
64
62
  }
65
63
 
66
64
  const jsenvGenerateLighthouseReport = async () => {
@@ -75,39 +73,63 @@ export const getLighthouseReportUsingHeadlessChrome = async (
75
73
  "--disk-cache-size=1",
76
74
  // "--disk-cache-dir=/dev/null",
77
75
  ]
78
- const chrome = await createOperation({
79
- cancellationToken,
80
- start: () => chromeLauncher.launch({ chromeFlags }),
81
- })
76
+ const chrome = await chromeLauncher.launch({ chromeFlags })
77
+ if (generateReportOperation.signal.aborted) {
78
+ return { aborted: true }
79
+ }
80
+
82
81
  const lighthouseOptions = {
83
82
  chromeFlags,
84
83
  port: chrome.port,
85
84
  }
86
85
 
87
86
  const reports = []
88
- await Array(runCount)
89
- .fill()
90
- .reduce(async (previous, _, index) => {
91
- await previous
92
- if (index > 0 && delayBetweenEachRunInSeconds) {
93
- await new Promise((resolve) => setTimeout(resolve, delayBetweenEachRunInSeconds * 1000))
94
- }
95
- const report = await generateOneLighthouseReport(url, {
96
- cancellationToken,
97
- lighthouseOptions,
98
- config,
99
- })
100
- reports.push(report)
101
- }, Promise.resolve())
87
+ try {
88
+ await Array(runCount)
89
+ .fill()
90
+ .reduce(async (previous, _, index) => {
91
+ generateReportOperation.throwIfAborted()
92
+ await previous
93
+
94
+ if (index > 0 && delayBetweenEachRunInSeconds) {
95
+ await new Promise((resolve) =>
96
+ setTimeout(resolve, delayBetweenEachRunInSeconds * 1000),
97
+ )
98
+ }
99
+ generateReportOperation.throwIfAborted()
100
+ const report = await generateOneLighthouseReport(url, {
101
+ lighthouseOptions,
102
+ config,
103
+ })
104
+ reports.push(report)
105
+ }, Promise.resolve())
106
+ } catch (e) {
107
+ if (Abort.isAbortError(e)) {
108
+ return { aborted: true }
109
+ }
110
+ throw e
111
+ }
102
112
 
103
113
  const lighthouseReport = computeMedianRun(reports)
114
+
115
+ if (log) {
116
+ logger.info(formatLighthouseReportForLog(lighthouseReport))
117
+ }
118
+
104
119
  await chrome.kill()
105
120
 
121
+ if (jsonFile || htmlFile) {
122
+ projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
123
+ }
124
+
106
125
  const promises = []
107
126
  if (jsonFile) {
108
127
  promises.push(
109
128
  (async () => {
110
- const jsonFileUrl = resolveUrl(jsonFileRelativeUrl, projectDirectoryUrl)
129
+ const jsonFileUrl = resolveUrl(
130
+ jsonFileRelativeUrl,
131
+ projectDirectoryUrl,
132
+ )
111
133
  const json = JSON.stringify(lighthouseReport, null, " ")
112
134
  await writeFile(jsonFileUrl, json)
113
135
  if (jsonFileLog) {
@@ -119,7 +141,10 @@ export const getLighthouseReportUsingHeadlessChrome = async (
119
141
  if (htmlFile) {
120
142
  promises.push(
121
143
  (async () => {
122
- const htmlFileUrl = resolveUrl(htmlFileRelativeUrl, projectDirectoryUrl)
144
+ const htmlFileUrl = resolveUrl(
145
+ htmlFileRelativeUrl,
146
+ projectDirectoryUrl,
147
+ )
123
148
  const html = ReportGenerator.generateReportHtml(lighthouseReport)
124
149
  await writeFile(htmlFileUrl, html)
125
150
  if (htmlFileLog) {
@@ -133,29 +158,19 @@ export const getLighthouseReportUsingHeadlessChrome = async (
133
158
  return lighthouseReport
134
159
  }
135
160
 
136
- return executeAsyncFunction(
137
- async () => {
138
- try {
139
- return await jsenvGenerateLighthouseReport()
140
- } finally {
141
- cleanup()
142
- }
143
- },
144
- {
145
- catchCancellation: true,
146
- considerUnhandledRejectionsAsExceptions: true,
147
- },
148
- )
161
+ try {
162
+ return await jsenvGenerateLighthouseReport()
163
+ } finally {
164
+ await generateReportOperation.end()
165
+ }
149
166
  }
150
167
 
151
168
  const generateOneLighthouseReport = async (
152
169
  url,
153
- { cancellationToken, lighthouseOptions, config },
170
+ { lighthouseOptions, config },
154
171
  ) => {
155
- const results = await createOperation({
156
- cancellationToken,
157
- start: () => lighthouse(url, lighthouseOptions, config),
158
- })
172
+ const lighthouse = require("lighthouse")
173
+ const results = await lighthouse(url, lighthouseOptions, config)
159
174
 
160
175
  // use results.lhr for the JS-consumeable output
161
176
  // https://github.com/GoogleChrome/lighthouse/blob/master/types/lhr.d.ts
@@ -38,8 +38,12 @@ export const createLighthouseImpactComment = ({
38
38
  }
39
39
 
40
40
  const bodyLines = [
41
- ...(beforeMergeGist ? [`<!-- before_merge_gist_id=${beforeMergeGist.id} -->`] : []),
42
- ...(afterMergeGist ? [`<!-- after_merge_gist_id=${afterMergeGist.id} -->`] : []),
41
+ ...(beforeMergeGist
42
+ ? [`<!-- before_merge_gist_id=${beforeMergeGist.id} -->`]
43
+ : []),
44
+ ...(afterMergeGist
45
+ ? [`<!-- after_merge_gist_id=${afterMergeGist.id} -->`]
46
+ : []),
43
47
  `<h4>Lighthouse impact</h4>`,
44
48
  ...(impactAnalysisEnabled
45
49
  ? [
@@ -76,19 +80,24 @@ const renderBody = ({
76
80
  pullRequestBase,
77
81
  pullRequestHead,
78
82
  }) => {
79
- return Object.keys(afterMergeLighthouseReport.categories).map((categoryName) => {
80
- return renderCategory(categoryName, {
81
- beforeMergeLighthouseReport,
82
- afterMergeLighthouseReport,
83
- pullRequestBase,
84
- pullRequestHead,
85
- })
86
- }).join(`
83
+ return Object.keys(afterMergeLighthouseReport.categories).map(
84
+ (categoryName) => {
85
+ return renderCategory(categoryName, {
86
+ beforeMergeLighthouseReport,
87
+ afterMergeLighthouseReport,
88
+ pullRequestBase,
89
+ pullRequestHead,
90
+ })
91
+ },
92
+ ).join(`
87
93
 
88
94
  `)
89
95
  }
90
96
 
91
- const renderCategory = (category, { beforeMergeLighthouseReport, afterMergeLighthouseReport }) => {
97
+ const renderCategory = (
98
+ category,
99
+ { beforeMergeLighthouseReport, afterMergeLighthouseReport },
100
+ ) => {
92
101
  const beforeMergeDisplayedScore = scoreToDisplayedScore(
93
102
  beforeMergeLighthouseReport.categories[category].score,
94
103
  )
@@ -114,7 +123,8 @@ const renderCategory = (category, { beforeMergeLighthouseReport, afterMergeLight
114
123
  </details>`
115
124
  }
116
125
 
117
- const scoreToDisplayedScore = (floatingNumber) => Math.round(floatingNumber * 100)
126
+ const scoreToDisplayedScore = (floatingNumber) =>
127
+ Math.round(floatingNumber * 100)
118
128
 
119
129
  const renderCategoryAudits = (
120
130
  category,
@@ -156,7 +166,10 @@ const renderCategoryAudits = (
156
166
  return
157
167
  }
158
168
 
159
- if (typeof beforeMergeAuditOutput === "number" && typeof afterMergeAuditOutput === "number") {
169
+ if (
170
+ typeof beforeMergeAuditOutput === "number" &&
171
+ typeof afterMergeAuditOutput === "number"
172
+ ) {
160
173
  const diff = afterMergeAuditOutput - beforeMergeAuditOutput
161
174
 
162
175
  audits.push([
@@ -170,7 +183,9 @@ const renderCategoryAudits = (
170
183
 
171
184
  audits.push([
172
185
  `<td nowrap>${auditId}</td>`,
173
- `<td nowrap>${beforeMergeAuditOutput === afterMergeAuditOutput ? "none" : "---"}</td>`,
186
+ `<td nowrap>${
187
+ beforeMergeAuditOutput === afterMergeAuditOutput ? "none" : "---"
188
+ }</td>`,
174
189
  `<td nowrap>${beforeMergeAuditOutput}</td>`,
175
190
  `<td nowrap>${afterMergeAuditOutput}</td>`,
176
191
  ])
@@ -237,7 +252,11 @@ const renderAudit = (audit) => {
237
252
  return null
238
253
  }
239
254
 
240
- const renderGistLinks = ({ beforeMergeGist, afterMergeGist, pullRequestBase }) => {
255
+ const renderGistLinks = ({
256
+ beforeMergeGist,
257
+ afterMergeGist,
258
+ pullRequestBase,
259
+ }) => {
241
260
  return `<sub>
242
261
  Impact analyzed comparing <a href="${gistIdToReportUrl(
243
262
  beforeMergeGist.id,
@@ -1,7 +1,7 @@
1
- export const logLighthouseReport = (lighthouseReport) => {
1
+ export const formatLighthouseReportForLog = (lighthouseReport) => {
2
2
  const scores = {}
3
3
  Object.keys(lighthouseReport.categories).forEach((name) => {
4
4
  scores[name] = lighthouseReport.categories[name].score
5
5
  })
6
- console.log(JSON.stringify(scores, null, " "))
6
+ return JSON.stringify(scores, null, " ")
7
7
  }
@@ -1,6 +1,10 @@
1
1
  /* eslint-disable new-cap */
2
2
  import { createDetailedMessage } from "@jsenv/logger"
3
- import { GET, POST, PATCH } from "@jsenv/github-pull-request-impact/src/internal/git_hub_api.js"
3
+ import {
4
+ GET,
5
+ POST,
6
+ PATCH,
7
+ } from "@jsenv/github-pull-request-impact/src/internal/git_hub_api.js"
4
8
 
5
9
  // https://developer.github.com/v3/gists/#create-a-gist
6
10
 
@@ -27,8 +31,10 @@ export const patchOrPostGists = async ({
27
31
  afterMergeGistId = gistIds.afterMergeGistId
28
32
  logger.debug(
29
33
  createDetailedMessage(`gists found in comment body`, {
30
- "before merging gist with lighthouse report": gistIdToUrl(beforeMergeGistId),
31
- "after merging gist with lighthouse report": gistIdToUrl(afterMergeGistId),
34
+ "before merging gist with lighthouse report":
35
+ gistIdToUrl(beforeMergeGistId),
36
+ "after merging gist with lighthouse report":
37
+ gistIdToUrl(afterMergeGistId),
32
38
  }),
33
39
  )
34
40
  } else {
@@ -39,10 +45,16 @@ export const patchOrPostGists = async ({
39
45
  logger.debug(`update or create both gists.`)
40
46
  let [beforeMergeGist, afterMergeGist] = await Promise.all([
41
47
  beforeMergeGistId
42
- ? GET(`https://api.github.com/gists/${beforeMergeGistId}`, { cancellationToken, githubToken })
48
+ ? GET(`https://api.github.com/gists/${beforeMergeGistId}`, {
49
+ cancellationToken,
50
+ githubToken,
51
+ })
43
52
  : null,
44
53
  afterMergeGistId
45
- ? GET(`https://api.github.com/gists/${afterMergeGistId}`, { cancellationToken, githubToken })
54
+ ? GET(`https://api.github.com/gists/${afterMergeGistId}`, {
55
+ cancellationToken,
56
+ githubToken,
57
+ })
46
58
  : null,
47
59
  ])
48
60
 
@@ -65,10 +77,14 @@ export const patchOrPostGists = async ({
65
77
  logger.info(`base gist updated`)
66
78
  } else {
67
79
  logger.info(`creating base gist`)
68
- beforeMergeGist = await POST(`https://api.github.com/gists`, beforeMergeGistBody, {
69
- cancellationToken,
70
- githubToken,
71
- })
80
+ beforeMergeGist = await POST(
81
+ `https://api.github.com/gists`,
82
+ beforeMergeGistBody,
83
+ {
84
+ cancellationToken,
85
+ githubToken,
86
+ },
87
+ )
72
88
  logger.info(`base gist created at ${gistIdToUrl(beforeMergeGist.id)}`)
73
89
  }
74
90
 
@@ -79,7 +95,9 @@ export const patchOrPostGists = async ({
79
95
  beforeMerge: false,
80
96
  })
81
97
  if (afterMergeGist) {
82
- logger.info(`updating after merge gist at ${gistIdToUrl(afterMergeGist.id)}`)
98
+ logger.info(
99
+ `updating after merge gist at ${gistIdToUrl(afterMergeGist.id)}`,
100
+ )
83
101
  afterMergeGist = await PATCH(
84
102
  `https://api.github.com/gists/${afterMergeGist.id}`,
85
103
  afterMergeGistBody,
@@ -91,10 +109,14 @@ export const patchOrPostGists = async ({
91
109
  logger.info(`after merge gist updated`)
92
110
  } else {
93
111
  logger.info(`creating after merge gist`)
94
- afterMergeGist = await POST(`https://api.github.com/gists`, afterMergeGistBody, {
95
- cancellationToken,
96
- githubToken,
97
- })
112
+ afterMergeGist = await POST(
113
+ `https://api.github.com/gists`,
114
+ afterMergeGistBody,
115
+ {
116
+ cancellationToken,
117
+ githubToken,
118
+ },
119
+ )
98
120
  logger.info(`after merge gist created at ${gistIdToUrl(afterMergeGist.id)}`)
99
121
  }
100
122
 
@@ -120,8 +142,12 @@ const createGistBody = (
120
142
  }
121
143
  }
122
144
 
123
- const beforeMergeGistIdRegex = new RegExp("<!-- before_merge_gist_id=([a-zA-Z0-9_]+) -->")
124
- const afterMergeGistIdRegex = new RegExp("<!-- after_merge_gist_id=([a-zA-Z0-9_]+) -->")
145
+ const beforeMergeGistIdRegex = new RegExp(
146
+ "<!-- before_merge_gist_id=([a-zA-Z0-9_]+) -->",
147
+ )
148
+ const afterMergeGistIdRegex = new RegExp(
149
+ "<!-- after_merge_gist_id=([a-zA-Z0-9_]+) -->",
150
+ )
125
151
 
126
152
  const gistIdsFromComment = (comment) => {
127
153
  const beforeMergeGistIdMatch = comment.body.match(beforeMergeGistIdRegex)
@@ -1,5 +1,6 @@
1
1
  import { commentGitHubPullRequestImpact } from "@jsenv/github-pull-request-impact"
2
- import { assertAndNormalizeDirectoryUrl, resolveUrl, readFileSystemNodeStat } from "@jsenv/util"
2
+ import { assertAndNormalizeDirectoryUrl, resolveUrl } from "@jsenv/filesystem"
3
+ import { importOneExportFromFile } from "@jsenv/dynamic-import-worker"
3
4
 
4
5
  import { patchOrPostGists } from "./internal/patchOrPostGists.js"
5
6
  import { createLighthouseImpactComment } from "./internal/createLighthouseImpactComment.js"
@@ -7,6 +8,8 @@ import { createLighthouseImpactComment } from "./internal/createLighthouseImpact
7
8
  export const reportLighthouseImpact = async ({
8
9
  logLevel,
9
10
  commandLogs = false,
11
+ // TODO: update { cancellationToken, cancelOnSIGINT } in "@jsenv/github-pull-request-impact"
12
+ // to use { signal, handleSIGINT } instead
10
13
  cancellationToken,
11
14
  cancelOnSIGINT,
12
15
  projectDirectoryUrl,
@@ -16,7 +19,7 @@ export const reportLighthouseImpact = async ({
16
19
  repositoryName,
17
20
  pullRequestNumber,
18
21
  installCommand = "npm install",
19
- moduleGeneratingLighthouseReportRelativeUrl, // rename this
22
+ lighthouseReportPath,
20
23
 
21
24
  runLink,
22
25
  commitInGeneratedByInfo,
@@ -24,14 +27,14 @@ export const reportLighthouseImpact = async ({
24
27
  skipGistWarning = false,
25
28
  }) => {
26
29
  projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
27
- if (typeof moduleGeneratingLighthouseReportRelativeUrl !== "string") {
30
+ if (typeof lighthouseReportPath !== "string") {
28
31
  throw new TypeError(
29
- `moduleGeneratingLighthouseReportRelativeUrl must be a string but received ${moduleGeneratingLighthouseReportRelativeUrl}`,
32
+ `lighthouseReportPath must be a string but received ${lighthouseReportPath}`,
30
33
  )
31
34
  }
32
35
  projectDirectoryUrl = assertAndNormalizeDirectoryUrl(projectDirectoryUrl)
33
- const moduleGeneratingLighthouseReportUrl = resolveUrl(
34
- moduleGeneratingLighthouseReportRelativeUrl,
36
+ const lighthouseReportUrl = resolveUrl(
37
+ lighthouseReportPath,
35
38
  projectDirectoryUrl,
36
39
  )
37
40
 
@@ -51,19 +54,9 @@ export const reportLighthouseImpact = async ({
51
54
 
52
55
  collectInfo: async ({ execCommandInProjectDirectory }) => {
53
56
  await execCommandInProjectDirectory(installCommand)
54
- await assertGenerateLighthouseReportFileExists(moduleGeneratingLighthouseReportUrl)
55
-
56
- const { generateLighthouseReport } = await import(
57
- `${moduleGeneratingLighthouseReportUrl}?cache_busting=${Date.now()}`
57
+ const lighthouseReport = await importOneExportFromFile(
58
+ lighthouseReportUrl,
58
59
  )
59
- if (typeof generateLighthouseReport !== "function") {
60
- throw new TypeError(
61
- `generateLighthouseReport export must be a function, got ${generateLighthouseReport}`,
62
- )
63
- }
64
-
65
- const lighthouseReport = await generateLighthouseReport()
66
-
67
60
  return { version: 1, data: lighthouseReport }
68
61
  },
69
62
  commentIdentifier: `<!-- Generated by @jsenv/lighthouse-impact -->`,
@@ -132,15 +125,3 @@ export const reportLighthouseImpact = async ({
132
125
  catchError,
133
126
  })
134
127
  }
135
-
136
- const assertGenerateLighthouseReportFileExists = async (fileUrl) => {
137
- const fileStat = await readFileSystemNodeStat(fileUrl, {
138
- nullIfNotFound: true,
139
- })
140
-
141
- if (!fileStat) {
142
- throw new Error(
143
- `Cannot find the file responsible to export generateLighthouseReport at ${fileUrl}`,
144
- )
145
- }
146
- }