@percy/cli-upload 1.0.0-beta.69 → 1.0.0-beta.72

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
@@ -4,30 +4,36 @@ Percy CLI command to uploade a directory of static images to Percy for diffing.
4
4
 
5
5
  ## Commands
6
6
  <!-- commands -->
7
- * [`percy upload DIRNAME`](#percy-upload-dirname)
7
+ * [`percy upload`](#percy-upload)
8
8
 
9
- ## `percy upload DIRNAME`
9
+ ### `percy upload`
10
10
 
11
11
  Upload a directory of images to Percy
12
12
 
13
13
  ```
14
- USAGE
15
- $ percy upload DIRNAME
16
-
17
- ARGUMENTS
18
- DIRNAME directory of images to upload
19
-
20
- OPTIONS
21
- -c, --config=config configuration file path
22
- -d, --dry-run prints a list of matching images to upload without uploading
23
- -e, --strip-extensions strips file extensions from snapshot names
24
- -f, --files=files [default: **/*.{png,jpg,jpeg}] one or more globs matching image file paths to upload
25
- -i, --ignore=ignore one or more globs matching image file paths to ignore
26
- -q, --quiet log errors only
27
- -v, --verbose log everything
28
- --silent log nothing
29
-
30
- EXAMPLE
14
+ Usage:
15
+ $ percy upload [options] <dirname>
16
+
17
+ Arguments:
18
+ dirname Directory of images to upload
19
+
20
+ Options:
21
+ -f, --files [pattern] One or more globs matching image file paths to upload (default:
22
+ "**/*.{png,jpg,jpeg}")
23
+ -i, --ignore <pattern> One or more globs matching image file paths to ignore
24
+ -e, --strip-extensions Strips file extensions from snapshot names
25
+
26
+ Percy options:
27
+ -c, --config <file> Config file path
28
+ -d, --dry-run Print snapshot names only
29
+
30
+ Global options:
31
+ -v, --verbose Log everything
32
+ -q, --quiet Log errors only
33
+ -s, --silent Log nothing
34
+ -h, --help Display command help
35
+
36
+ Examples:
31
37
  $ percy upload ./images
32
38
  ```
33
39
  <!-- commandsstop -->
package/dist/resources.js CHANGED
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = createImageResources;
6
+ exports.createImageResources = createImageResources;
7
+ exports.default = void 0;
7
8
 
8
9
  var _path = _interopRequireDefault(require("path"));
9
10
 
@@ -35,7 +36,7 @@ function createImageResource(url, content, mimetype) {
35
36
  // designed to display an image at it's native size without margins or padding.
36
37
 
37
38
 
38
- function createImageResources(filename, content, width, height) {
39
+ function createImageResources(filename, content, size) {
39
40
  let {
40
41
  dir,
41
42
  name,
@@ -58,8 +59,11 @@ function createImageResources(filename, content, width, height) {
58
59
  </style>
59
60
  </head>
60
61
  <body>
61
- <img src="${imageUrl}" width="${width}px" height="${height}px"/>
62
+ <img src="${imageUrl}" width="${size.width}px" height="${size.height}px"/>
62
63
  </body>
63
64
  </html>
64
65
  `), createImageResource(imageUrl, content, mimetype)];
65
- }
66
+ }
67
+
68
+ var _default = createImageResources;
69
+ exports.default = _default;
package/dist/upload.js ADDED
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.upload = exports.default = void 0;
7
+
8
+ var _fs = _interopRequireDefault(require("fs"));
9
+
10
+ var _path = _interopRequireDefault(require("path"));
11
+
12
+ var _cliCommand = _interopRequireDefault(require("@percy/cli-command"));
13
+
14
+ var UploadConfig = _interopRequireWildcard(require("./config"));
15
+
16
+ var _package = _interopRequireDefault(require("../package.json"));
17
+
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+
20
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
21
+
22
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
+
24
+ const ALLOWED_FILE_TYPES = /\.(png|jpg|jpeg)$/i;
25
+ const upload = (0, _cliCommand.default)('upload', {
26
+ description: 'Upload a directory of images to Percy',
27
+ args: [{
28
+ name: 'dirname',
29
+ description: 'Directory of images to upload',
30
+ required: true,
31
+ validate: dir => {
32
+ if (!_fs.default.existsSync(dir)) {
33
+ throw new Error(`Not found: ${dir}`);
34
+ } else if (!_fs.default.lstatSync(dir).isDirectory()) {
35
+ throw new Error(`Not a directory: ${dir}`);
36
+ }
37
+ }
38
+ }],
39
+ flags: [{
40
+ name: 'files',
41
+ description: 'One or more globs matching image file paths to upload',
42
+ default: UploadConfig.schema.upload.properties.files.default,
43
+ percyrc: 'upload.files',
44
+ type: 'pattern',
45
+ multiple: true,
46
+ short: 'f'
47
+ }, {
48
+ name: 'ignore',
49
+ description: 'One or more globs matching image file paths to ignore',
50
+ percyrc: 'upload.ignore',
51
+ type: 'pattern',
52
+ multiple: true,
53
+ short: 'i'
54
+ }, {
55
+ name: 'strip-extensions',
56
+ description: 'Strips file extensions from snapshot names',
57
+ percyrc: 'upload.stripExtensions',
58
+ short: 'e'
59
+ }],
60
+ examples: ['$0 ./images'],
61
+ percy: {
62
+ clientInfo: `${_package.default.name}/${_package.default.version}`,
63
+ environmentInfo: `node/${process.version}`,
64
+ discoveryFlags: false,
65
+ deferUploads: true
66
+ },
67
+ config: {
68
+ schemas: [UploadConfig.schema],
69
+ migrations: [UploadConfig.migration]
70
+ }
71
+ }, async function* ({
72
+ flags,
73
+ args,
74
+ percy,
75
+ log,
76
+ exit
77
+ }) {
78
+ if (!percy) exit(0, 'Percy is disabled');
79
+ let config = percy.config.upload;
80
+ let {
81
+ default: globby
82
+ } = await Promise.resolve().then(() => _interopRequireWildcard(require('globby')));
83
+ let pathnames = yield globby(config.files, {
84
+ ignore: [].concat(config.ignore || []),
85
+ cwd: args.dirname
86
+ });
87
+
88
+ if (!pathnames.length) {
89
+ exit(1, `No matching files found in '${args.dirname}'`);
90
+ }
91
+
92
+ let {
93
+ default: imageSize
94
+ } = await Promise.resolve().then(() => _interopRequireWildcard(require('image-size')));
95
+ let {
96
+ createImageResources
97
+ } = await Promise.resolve().then(() => _interopRequireWildcard(require('./resources'))); // the internal upload queue shares a concurrency with the snapshot queue
98
+
99
+ percy.setConfig({
100
+ discovery: {
101
+ concurrency: config.concurrency
102
+ }
103
+ }); // do not launch a browser when starting
104
+
105
+ yield percy.start({
106
+ browser: false
107
+ });
108
+
109
+ for (let filename of pathnames) {
110
+ let file = _path.default.parse(filename);
111
+
112
+ let name = config.stripExtensions ? _path.default.join(file.dir, file.name) : filename;
113
+
114
+ if (!ALLOWED_FILE_TYPES.test(filename)) {
115
+ log.info(`Skipping unsupported file type: ${filename}`);
116
+ } else {
117
+ if (percy.dryRun) log.info(`Snapshot found: ${name}`);
118
+
119
+ percy._scheduleUpload(filename, async () => {
120
+ let filepath = _path.default.resolve(args.dirname, filename);
121
+
122
+ let buffer = _fs.default.readFileSync(filepath); // width and height is clamped to API min and max
123
+
124
+
125
+ let size = imageSize(filepath);
126
+ let widths = [Math.max(10, Math.min(size.width, 2000))];
127
+ let minHeight = Math.max(10, Math.min(size.height, 2000));
128
+ let resources = createImageResources(filename, buffer, size);
129
+ return {
130
+ name,
131
+ widths,
132
+ minHeight,
133
+ resources
134
+ };
135
+ }).then(() => {
136
+ log.info(`Snapshot uploaded: ${name}`);
137
+ });
138
+ }
139
+ }
140
+
141
+ try {
142
+ yield* percy.stop();
143
+ } catch (error) {
144
+ await percy.stop(true);
145
+ throw error;
146
+ }
147
+ });
148
+ exports.upload = upload;
149
+ var _default = upload;
150
+ exports.default = _default;
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "@percy/cli-upload",
3
- "version": "1.0.0-beta.69",
3
+ "version": "1.0.0-beta.72",
4
4
  "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/percy/cli",
8
+ "directory": "packages/cli-upload"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
5
13
  "main": "dist/index.js",
6
14
  "files": [
7
- "dist",
8
- "oclif.manifest.json"
15
+ "dist"
9
16
  ],
10
17
  "engines": {
11
18
  "node": ">=12"
@@ -13,33 +20,21 @@
13
20
  "scripts": {
14
21
  "build": "node ../../scripts/build",
15
22
  "lint": "eslint --ignore-path ../../.gitignore .",
16
- "postbuild": "oclif-dev manifest",
17
- "readme": "oclif-dev readme",
23
+ "readme": "percy-cli-readme",
18
24
  "test": "node ../../scripts/test",
19
25
  "test:coverage": "yarn test --coverage"
20
26
  },
21
- "publishConfig": {
22
- "access": "public"
23
- },
24
- "oclif": {
25
- "bin": "percy",
26
- "commands": "./dist/commands",
27
- "hooks": {
28
- "init": "./dist/hooks/init"
29
- }
27
+ "@percy/cli": {
28
+ "commands": [
29
+ "./dist/upload.js"
30
+ ]
30
31
  },
31
32
  "dependencies": {
32
- "@percy/cli-command": "1.0.0-beta.69",
33
- "@percy/client": "1.0.0-beta.69",
34
- "@percy/config": "1.0.0-beta.69",
35
- "@percy/logger": "1.0.0-beta.69",
33
+ "@percy/cli-command": "1.0.0-beta.72",
34
+ "@percy/client": "1.0.0-beta.72",
35
+ "@percy/logger": "1.0.0-beta.72",
36
36
  "globby": "^11.0.4",
37
37
  "image-size": "^1.0.0"
38
38
  },
39
- "repository": {
40
- "type": "git",
41
- "url": "https://github.com/percy/cli",
42
- "directory": "packages/cli-upload"
43
- },
44
- "gitHead": "99b0617016a07c9d7d4ca37c1442011c904cf860"
39
+ "gitHead": "6219287e18a0cacb609d0c2696a5785abc9009b9"
45
40
  }
@@ -1,188 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.Upload = void 0;
7
-
8
- var _fs = _interopRequireDefault(require("fs"));
9
-
10
- var _path = _interopRequireDefault(require("path"));
11
-
12
- var _cliCommand = _interopRequireWildcard(require("@percy/cli-command"));
13
-
14
- var _logger = _interopRequireDefault(require("@percy/logger"));
15
-
16
- var _globby = _interopRequireDefault(require("globby"));
17
-
18
- var _imageSize = _interopRequireDefault(require("image-size"));
19
-
20
- var _client = _interopRequireDefault(require("@percy/client"));
21
-
22
- var _queue = _interopRequireDefault(require("@percy/core/dist/queue"));
23
-
24
- var _resources = _interopRequireDefault(require("../resources"));
25
-
26
- var _config = require("../config");
27
-
28
- var _package = _interopRequireDefault(require("../../package.json"));
29
-
30
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
31
-
32
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
33
-
34
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
-
36
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
37
-
38
- const ALLOWED_FILE_TYPES = /^\.(png|jpg|jpeg)$/i;
39
-
40
- class Upload extends _cliCommand.default {
41
- constructor(...args) {
42
- super(...args);
43
-
44
- _defineProperty(this, "log", (0, _logger.default)('cli:upload'));
45
- }
46
-
47
- async run() {
48
- if (!this.isPercyEnabled()) {
49
- return this.log.info('Percy is disabled. Skipping upload');
50
- }
51
-
52
- let {
53
- dirname
54
- } = this.args;
55
- let {
56
- 'dry-run': dry
57
- } = this.flags;
58
-
59
- if (!_fs.default.existsSync(dirname)) {
60
- return this.error(`Not found: ${dirname}`);
61
- } else if (!_fs.default.lstatSync(dirname).isDirectory()) {
62
- return this.error(`Not a directory: ${dirname}`);
63
- }
64
-
65
- let {
66
- upload: conf
67
- } = this.percyrc();
68
- this.queue = new _queue.default(conf.concurrency);
69
- let paths = await (0, _globby.default)(conf.files, {
70
- ignore: [].concat(conf.ignore || []),
71
- cwd: dirname
72
- });
73
- let l = paths.length;
74
- if (!l) this.error(`No matching files found in '${dirname}'`);
75
- paths.sort();
76
- this.client = new _client.default({
77
- clientInfo: `${_package.default.name}/${_package.default.version}`,
78
- environmentInfo: `node/${process.version}`
79
- });
80
-
81
- if (dry) {
82
- this.log.info(`Found ${l} snapshot${l !== 1 ? 's' : ''}`);
83
- } else {
84
- let {
85
- data: build
86
- } = await this.client.createBuild();
87
- let {
88
- 'build-number': number,
89
- 'web-url': url
90
- } = build.attributes;
91
- this.build = {
92
- id: build.id,
93
- number,
94
- url
95
- };
96
- this.log.info('Percy has started!');
97
- }
98
-
99
- for (let filename of paths) {
100
- let file = _path.default.parse(filename);
101
-
102
- if (!ALLOWED_FILE_TYPES.test(file.ext)) {
103
- this.log.info(`Skipping unsupported file type: ${filename}`);
104
- continue;
105
- }
106
-
107
- let name = conf.stripExtensions ? _path.default.join(file.dir, file.name) : filename;
108
- if (dry) this.log.info(`Snapshot found: ${name}`);else this.snapshot(name, filename, dirname);
109
- }
110
- } // Push a snapshot upload to the queue
111
-
112
-
113
- snapshot(name, filename, dirname) {
114
- this.queue.push(`upload/${name}`, async () => {
115
- let filepath = _path.default.resolve(dirname, filename);
116
-
117
- let {
118
- width,
119
- height
120
- } = (0, _imageSize.default)(filepath);
121
-
122
- let buffer = _fs.default.readFileSync(filepath);
123
-
124
- await this.client.sendSnapshot(this.build.id, {
125
- // width and height is clamped to API min and max
126
- widths: [Math.max(10, Math.min(width, 2000))],
127
- minHeight: Math.max(10, Math.min(height, 2000)),
128
- resources: (0, _resources.default)(filename, buffer, width, height),
129
- name
130
- });
131
- this.log.info(`Snapshot uploaded: ${name}`);
132
- });
133
- } // Finalize the build when finished
134
-
135
-
136
- async finally(error) {
137
- var _this$build;
138
-
139
- if (!((_this$build = this.build) !== null && _this$build !== void 0 && _this$build.id)) return;
140
- if (error) this.queue.close(true);
141
- if (this.closing) return;
142
- this.closing = true;
143
- await this.queue.empty(s => {
144
- this.log.progress(`Uploading ${s} snapshot${s !== 1 ? 's' : ''}...`, !!s);
145
- });
146
- await this.client.finalizeBuild(this.build.id);
147
- this.log.info(`Finalized build #${this.build.number}: ${this.build.url}`);
148
- }
149
-
150
- }
151
-
152
- exports.Upload = Upload;
153
-
154
- _defineProperty(Upload, "description", 'Upload a directory of images to Percy');
155
-
156
- _defineProperty(Upload, "args", [{
157
- name: 'dirname',
158
- description: 'directory of images to upload',
159
- required: true
160
- }]);
161
-
162
- _defineProperty(Upload, "flags", { ..._cliCommand.flags.logging,
163
- ..._cliCommand.flags.config,
164
- files: _cliCommand.flags.string({
165
- char: 'f',
166
- multiple: true,
167
- description: 'one or more globs matching image file paths to upload',
168
- default: _config.schema.upload.properties.files.default,
169
- percyrc: 'upload.files'
170
- }),
171
- ignore: _cliCommand.flags.string({
172
- char: 'i',
173
- multiple: true,
174
- description: 'one or more globs matching image file paths to ignore',
175
- percyrc: 'upload.ignore'
176
- }),
177
- 'strip-extensions': _cliCommand.flags.boolean({
178
- char: 'e',
179
- description: 'strips file extensions from snapshot names',
180
- percyrc: 'upload.stripExtensions'
181
- }),
182
- 'dry-run': _cliCommand.flags.boolean({
183
- char: 'd',
184
- description: 'prints a list of matching images to upload without uploading'
185
- })
186
- });
187
-
188
- _defineProperty(Upload, "examples", ['$ percy upload ./images']);
@@ -1,22 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = _default;
7
-
8
- var _config = _interopRequireDefault(require("@percy/config"));
9
-
10
- var UploadConfig = _interopRequireWildcard(require("../config"));
11
-
12
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
-
14
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
-
16
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
-
18
- function _default() {
19
- _config.default.addSchema(UploadConfig.schema);
20
-
21
- _config.default.addMigration(UploadConfig.migration);
22
- }
@@ -1 +0,0 @@
1
- {"version":"1.0.0-beta.69","commands":{"upload":{"id":"upload","description":"Upload a directory of images to Percy","pluginName":"@percy/cli-upload","pluginType":"core","aliases":[],"examples":["$ percy upload ./images"],"flags":{"verbose":{"name":"verbose","type":"boolean","char":"v","description":"log everything","allowNo":false},"quiet":{"name":"quiet","type":"boolean","char":"q","description":"log errors only","allowNo":false},"silent":{"name":"silent","type":"boolean","description":"log nothing","allowNo":false},"config":{"name":"config","type":"option","char":"c","description":"configuration file path"},"files":{"name":"files","type":"option","char":"f","description":"one or more globs matching image file paths to upload","default":"**/*.{png,jpg,jpeg}"},"ignore":{"name":"ignore","type":"option","char":"i","description":"one or more globs matching image file paths to ignore"},"strip-extensions":{"name":"strip-extensions","type":"boolean","char":"e","description":"strips file extensions from snapshot names","allowNo":false},"dry-run":{"name":"dry-run","type":"boolean","char":"d","description":"prints a list of matching images to upload without uploading","allowNo":false}},"args":[{"name":"dirname","description":"directory of images to upload","required":true}]}}}