@percy/env 1.0.0-beta.8 → 1.0.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/dist/dotenv.js CHANGED
@@ -1,27 +1,62 @@
1
- "use strict";
1
+ import fs from 'fs'; // Heavily inspired by dotenv-rails
2
+ // https://github.com/bkeepers/dotenv
3
+ // matches each valid line of a dotenv file
2
4
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.config = config;
5
+ const LINE_REG = new RegExp([// key with optional export
6
+ '^\\s*(?:export\\s+)?(?<key>[\\w.]+)', // separator
7
+ '(?:\\s*=\\s*?|:\\s+?)(?:', // single quoted value or
8
+ '\\s*(?<squote>\')(?<sval>(?:\\\\\'|[^\'])*)\'|', // double quoted value or
9
+ '\\s*(?<dquote>")(?<dval>(?:\\\\"|[^"])*)"|', // unquoted value
10
+ '(?<uval>[^#\\r\\n]+))?', // optional comment
11
+ '\\s*(?:#.*)?$'].join(''), 'gm'); // interpolate variable substitutions
7
12
 
8
- const dotenv = require('dotenv'); // mimic dotenv-rails file hierarchy
9
- // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
13
+ const INTERPOLATE_REG = /(.?)(\${?([a-zA-Z0-9_]+)?}?)/g; // expand newlines
10
14
 
15
+ const EXPAND_CRLF_REG = /\\(?:(r)|n)/g; // unescape characters
11
16
 
12
- function config() {
17
+ const UNESC_CHAR_REG = /\\([^$])/g;
18
+ export function load() {
19
+ // don't load dotenv files when disabled
20
+ if (process.env.PERCY_DISABLE_DOTENV) return;
13
21
  let {
14
- NODE_ENV: env,
15
- PERCY_DISABLE_DOTENV: disable
16
- } = process.env; // don't load dotenv files when disabled
22
+ NODE_ENV
23
+ } = process.env; // dotenv filepaths ordered by priority
17
24
 
18
- if (disable) return;
19
- let paths = [env && `.env.${env}.local`, // .env.local is not loaded in test environments
20
- env === 'test' ? null : '.env.local', env && `.env.${env}`, '.env'].filter(Boolean);
25
+ let paths = [NODE_ENV && `.env.${NODE_ENV}.local`, NODE_ENV !== 'test' && '.env.local', NODE_ENV && `.env.${NODE_ENV}`, '.env']; // load each dotenv file synchronously
21
26
 
22
27
  for (let path of paths) {
23
- dotenv.config({
24
- path
25
- });
28
+ try {
29
+ let src = fs.readFileSync(path, {
30
+ encoding: 'utf-8'
31
+ }); // iterate over each matching line
32
+
33
+ for (let {
34
+ groups: match
35
+ } of src.matchAll(LINE_REG)) {
36
+ let value = match.sval ?? match.dval ?? match.uval ?? ''; // if double quoted, expand newlines
37
+
38
+ if (match.dquote) {
39
+ value = value.replace(EXPAND_CRLF_REG, (_, r) => r ? '\r' : '\n');
40
+ } // unescape characters
41
+
42
+
43
+ value = value.replace(UNESC_CHAR_REG, '$1'); // if not single quoted, interpolate substitutions
44
+
45
+ if (!match.squote) {
46
+ value = value.replace(INTERPOLATE_REG, (_, pre, ref, key) => {
47
+ if (pre === '\\') return ref; // escaped reference
48
+
49
+ return pre + (process.env[key] ?? '');
50
+ });
51
+ } // set process.env if not already
52
+
53
+
54
+ if (!Object.prototype.hasOwnProperty.call(process.env, match.key)) {
55
+ process.env[match.key] = value;
56
+ }
57
+ }
58
+ } catch (e) {// silent error
59
+ }
26
60
  }
27
- }
61
+ }
62
+ export * as default from './dotenv.js';
@@ -1,13 +1,5 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _git = require("./git");
9
-
10
- class PercyEnvironment {
1
+ import { getCommitData, getJenkinsSha, github } from './utils.js';
2
+ export class PercyEnv {
11
3
  constructor(vars = process.env) {
12
4
  this.vars = vars;
13
5
  } // used for getter switch statements
@@ -55,11 +47,9 @@ class PercyEnvironment {
55
47
 
56
48
 
57
49
  get info() {
58
- var _this$vars$PERCY_GITH;
59
-
60
50
  switch (this.ci) {
61
51
  case 'github':
62
- return `github/${(_this$vars$PERCY_GITH = this.vars.PERCY_GITHUB_ACTION) !== null && _this$vars$PERCY_GITH !== void 0 ? _this$vars$PERCY_GITH : 'unknown'}`;
52
+ return this.vars.PERCY_GITHUB_ACTION ? `github/${this.vars.PERCY_GITHUB_ACTION}` : this.ci;
63
53
 
64
54
  case 'gitlab':
65
55
  return `gitlab/${this.vars.CI_SERVER_VERSION}`;
@@ -79,6 +69,8 @@ class PercyEnvironment {
79
69
  }
80
70
 
81
71
  let commit = (() => {
72
+ var _github$pull_request;
73
+
82
74
  switch (this.ci) {
83
75
  case 'travis':
84
76
  return this.vars.TRAVIS_COMMIT;
@@ -87,7 +79,7 @@ class PercyEnvironment {
87
79
  return this.vars.ghprbActualCommit || this.vars.GIT_COMMIT;
88
80
 
89
81
  case 'jenkins':
90
- return (0, _git.getJenkinsSha)() || this.vars.GIT_COMMIT;
82
+ return getJenkinsSha() || this.vars.GIT_COMMIT;
91
83
 
92
84
  case 'circle':
93
85
  return this.vars.CIRCLE_SHA1;
@@ -124,7 +116,7 @@ class PercyEnvironment {
124
116
  return this.vars.BITBUCKET_COMMIT;
125
117
 
126
118
  case 'github':
127
- return this.vars.GITHUB_SHA;
119
+ return ((_github$pull_request = github(this.vars).pull_request) === null || _github$pull_request === void 0 ? void 0 : _github$pull_request.head.sha) || this.vars.GITHUB_SHA;
128
120
  }
129
121
  })();
130
122
 
@@ -138,7 +130,7 @@ class PercyEnvironment {
138
130
  }
139
131
 
140
132
  let branch = (() => {
141
- var _this$vars$GITHUB_REF;
133
+ var _github$pull_request2;
142
134
 
143
135
  switch (this.ci) {
144
136
  case 'travis':
@@ -184,14 +176,14 @@ class PercyEnvironment {
184
176
  return this.vars.BITBUCKET_BRANCH;
185
177
 
186
178
  case 'github':
187
- return ((_this$vars$GITHUB_REF = this.vars.GITHUB_REF) === null || _this$vars$GITHUB_REF === void 0 ? void 0 : _this$vars$GITHUB_REF.match(/^refs\//)) ? this.vars.GITHUB_REF.replace(/^refs\/\w+?\//, '') : this.vars.GITHUB_REF;
179
+ return ((_github$pull_request2 = github(this.vars).pull_request) === null || _github$pull_request2 === void 0 ? void 0 : _github$pull_request2.head.ref) || this.vars.GITHUB_REF;
188
180
 
189
181
  case 'netlify':
190
182
  return this.vars.HEAD;
191
183
  }
192
184
  })();
193
185
 
194
- return branch || null;
186
+ return (branch === null || branch === void 0 ? void 0 : branch.replace(/^refs\/\w+?\//, '')) || null;
195
187
  } // pull request number
196
188
 
197
189
 
@@ -201,7 +193,7 @@ class PercyEnvironment {
201
193
  }
202
194
 
203
195
  let pr = (() => {
204
- var _this$vars$CI_PULL_RE, _this$vars$PULL_REQUE;
196
+ var _this$vars$CI_PULL_RE, _this$vars$PULL_REQUE, _github$pull_request3;
205
197
 
206
198
  switch (this.ci) {
207
199
  case 'travis':
@@ -225,11 +217,14 @@ class PercyEnvironment {
225
217
  case 'buildkite':
226
218
  return this.vars.BUILDKITE_PULL_REQUEST !== 'false' && this.vars.BUILDKITE_PULL_REQUEST;
227
219
 
220
+ case 'heroku':
221
+ return this.vars.HEROKU_PR_NUMBER;
222
+
228
223
  case 'gitlab':
229
224
  return this.vars.CI_MERGE_REQUEST_IID;
230
225
 
231
226
  case 'azure':
232
- return this.vars.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER;
227
+ return this.vars.SYSTEM_PULLREQUEST_PULLREQUESTID || this.vars.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER;
233
228
 
234
229
  case 'appveyor':
235
230
  return this.vars.APPVEYOR_PULL_REQUEST_NUMBER;
@@ -242,15 +237,21 @@ class PercyEnvironment {
242
237
 
243
238
  case 'netlify':
244
239
  return this.vars.PULL_REQUEST !== 'false' && this.vars.REVIEW_ID;
240
+
241
+ case 'github':
242
+ return (_github$pull_request3 = github(this.vars).pull_request) === null || _github$pull_request3 === void 0 ? void 0 : _github$pull_request3.number;
245
243
  }
246
244
  })();
247
245
 
248
246
  return pr || null;
249
- } // parallel nonce & total
247
+ } // parallel total & nonce
250
248
 
251
249
 
252
250
  get parallel() {
253
- let nonce = (() => {
251
+ let total = parseInt(this.vars.PERCY_PARALLEL_TOTAL, 10);
252
+ if (!Number.isInteger(total)) total = null; // no nonce if no total
253
+
254
+ let nonce = total && (() => {
254
255
  var _this$vars$BUILD_TAG;
255
256
 
256
257
  if (this.vars.PERCY_PARALLEL_NONCE) {
@@ -299,49 +300,21 @@ class PercyEnvironment {
299
300
 
300
301
  case 'bitbucket':
301
302
  return this.vars.BITBUCKET_BUILD_NUMBER;
302
- }
303
- })();
304
-
305
- let total = (() => {
306
- if (this.vars.PERCY_PARALLEL_TOTAL) {
307
- return this.vars.PERCY_PARALLEL_TOTAL;
308
- }
309
-
310
- switch (this.ci) {
311
- case 'travis':
312
- return this.vars.CI_NODE_TOTAL;
313
-
314
- case 'circle':
315
- return this.vars.CIRCLE_NODE_TOTAL;
316
-
317
- case 'codeship':
318
- return this.vars.CI_NODE_TOTAL;
319
-
320
- case 'semaphore':
321
- return this.vars.SEMAPHORE_THREAD_COUNT;
322
303
 
323
- case 'buildkite':
324
- return this.vars.BUILDKITE_PARALLEL_JOB_COUNT;
325
-
326
- case 'heroku':
327
- return this.vars.CI_NODE_TOTAL;
328
-
329
- case 'azure':
330
- // SYSTEM_TOTALJOBSINPHASE is set for parallel builds and non-parallel matrix builds, so
331
- // check build strategy is parallel by ensuring SYSTEM_PARALLELEXECUTIONTYPE == MultiMachine
332
- return this.vars.SYSTEM_PARALLELEXECUTIONTYPE === 'MultiMachine' && this.vars.SYSTEM_TOTALJOBSINPHASE;
304
+ case 'github':
305
+ return this.vars.GITHUB_RUN_ID;
333
306
  }
334
307
  })();
335
308
 
336
309
  return {
337
- nonce: nonce || null,
338
- total: total ? parseInt(total) : null
310
+ total: total || null,
311
+ nonce: nonce || null
339
312
  };
340
313
  } // git information for the current commit
341
314
 
342
315
 
343
316
  get git() {
344
- return (0, _git.getCommitData)(this.commit, this.branch, this.vars);
317
+ return getCommitData(this.commit, this.branch, this.vars);
345
318
  } // manually set build commit and branch targets
346
319
 
347
320
 
@@ -365,9 +338,7 @@ class PercyEnvironment {
365
338
 
366
339
  } // cache getters on initial call so subsequent calls are not re-computed
367
340
 
368
-
369
- exports.default = PercyEnvironment;
370
- Object.defineProperties(PercyEnvironment.prototype, Object.entries(Object.getOwnPropertyDescriptors(PercyEnvironment.prototype)).reduce((proto, [key, {
341
+ Object.defineProperties(PercyEnv.prototype, Object.entries(Object.getOwnPropertyDescriptors(PercyEnv.prototype)).reduce((proto, [key, {
371
342
  get,
372
343
  ...descr
373
344
  }]) => !get ? proto : Object.assign(proto, {
@@ -381,4 +352,5 @@ Object.defineProperties(PercyEnvironment.prototype, Object.entries(Object.getOwn
381
352
  }
382
353
 
383
354
  })
384
- }), {}));
355
+ }), {}));
356
+ export default PercyEnv;
package/dist/index.js CHANGED
@@ -1,17 +1,5 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "default", {
7
- enumerable: true,
8
- get: function () {
9
- return _environment.default;
10
- }
11
- });
12
-
13
- var _environment = _interopRequireDefault(require("./environment"));
14
-
15
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
-
17
- require('./dotenv').config();
1
+ import PercyEnv from './environment.js';
2
+ import dotenv from './dotenv.js';
3
+ dotenv.load();
4
+ export { PercyEnv };
5
+ export default PercyEnv;
@@ -1,40 +1,26 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.git = git;
7
- exports.getCommitData = getCommitData;
8
- exports.getJenkinsSha = getJenkinsSha;
9
-
10
- var _child_process = require("child_process");
11
-
1
+ import fs from 'fs';
2
+ import cp from 'child_process';
12
3
  const GIT_COMMIT_FORMAT = ['COMMIT_SHA:%H', 'AUTHOR_NAME:%an', 'AUTHOR_EMAIL:%ae', 'COMMITTER_NAME:%cn', 'COMMITTER_EMAIL:%ce', 'COMMITTED_DATE:%ai', // order is important, this must come last because the regex is a multiline match.
13
4
  'COMMIT_MESSAGE:%B'].join('%n'); // git show format uses %n for newlines.
14
5
 
15
- function git(args) {
6
+ export function git(args) {
16
7
  try {
17
- let result = (0, _child_process.execSync)(`git ${args}`, {
18
- stdio: 'ignore'
8
+ return cp.execSync(`git ${args}`, {
9
+ stdio: ['ignore', 'pipe', 'ignore'],
10
+ encoding: 'utf-8'
19
11
  });
20
-
21
- if (result && result.status === 0) {
22
- return result.stdout.trim();
23
- }
24
- } catch (e) {// do something?
12
+ } catch (e) {
13
+ return '';
25
14
  }
26
-
27
- return '';
28
15
  } // get raw commit data
29
16
 
30
-
31
- function getCommitData(sha, branch, vars = {}) {
17
+ export function getCommitData(sha, branch, vars = {}) {
32
18
  let raw = git(`show ${sha || 'HEAD'} --quiet --format=${GIT_COMMIT_FORMAT}`); // prioritize PERCY_GIT_* vars and fallback to GIT_* vars
33
19
 
34
20
  let get = key => {
35
21
  var _raw$match;
36
22
 
37
- return vars[`PERCY_GIT_${key}`] || ((_raw$match = raw.match(new RegExp(`${key}:(.*)`, 'm'))) === null || _raw$match === void 0 ? void 0 : _raw$match[1]) || vars[`GIT_${key}`] || null;
23
+ return vars[`PERCY_GIT_${key}`] || ((_raw$match = raw.match(new RegExp(`^${key}:(.*)$`, 'm'))) === null || _raw$match === void 0 ? void 0 : _raw$match[1]) || vars[`GIT_${key}`] || null;
38
24
  };
39
25
 
40
26
  return {
@@ -49,8 +35,19 @@ function getCommitData(sha, branch, vars = {}) {
49
35
  };
50
36
  } // the sha needed from Jenkins merge commits is the parent sha
51
37
 
52
-
53
- function getJenkinsSha() {
38
+ export function getJenkinsSha() {
54
39
  let data = getCommitData();
55
40
  return data.authorName === 'Jenkins' && data.authorEmail === 'nobody@nowhere' && data.message.match(/^Merge commit [^\s]+ into HEAD$/) && git('rev-parse HEAD^');
41
+ } // github actions are triggered by webhook events which are saved to the filesystem
42
+
43
+ export function github({
44
+ GITHUB_EVENT_PATH
45
+ }) {
46
+ if (!github.payload && GITHUB_EVENT_PATH && fs.existsSync(GITHUB_EVENT_PATH)) {
47
+ try {
48
+ github.payload = JSON.parse(fs.readFileSync(GITHUB_EVENT_PATH));
49
+ } catch {}
50
+ }
51
+
52
+ return github.payload || (github.payload = {});
56
53
  }
package/package.json CHANGED
@@ -1,28 +1,33 @@
1
1
  {
2
2
  "name": "@percy/env",
3
- "version": "1.0.0-beta.8",
3
+ "version": "1.0.1",
4
4
  "license": "MIT",
5
- "main": "dist/index.js",
6
- "files": [
7
- "dist"
8
- ],
9
- "scripts": {
10
- "build": "babel --root-mode upward src --out-dir dist",
11
- "lint": "eslint --ignore-path ../../.gitignore .",
12
- "test": "cross-env NODE_ENV=test mocha",
13
- "test:coverage": "nyc yarn test"
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/percy/cli",
8
+ "directory": "packages/env"
14
9
  },
15
10
  "publishConfig": {
16
11
  "access": "public"
17
12
  },
18
- "mocha": {
19
- "require": "../../scripts/babel-register"
13
+ "engines": {
14
+ "node": ">=14"
20
15
  },
21
- "devDependencies": {
22
- "mock-require": "^3.0.3"
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "type": "module",
21
+ "exports": {
22
+ ".": "./dist/index.js",
23
+ "./utils": "./dist/utils.js",
24
+ "./test/helpers": "./test/helpers.js"
23
25
  },
24
- "dependencies": {
25
- "dotenv": "^8.2.0"
26
+ "scripts": {
27
+ "build": "node ../../scripts/build",
28
+ "lint": "eslint --ignore-path ../../.gitignore .",
29
+ "test": "node ../../scripts/test",
30
+ "test:coverage": "yarn test --coverage"
26
31
  },
27
- "gitHead": "6015850e7c20c130d625fcb327b10d7513b35707"
32
+ "gitHead": "38917e6027299d6cd86008e2ccd005d90bbf89c0"
28
33
  }