1 | 'use strict';
|
2 |
|
3 | var exec = require('child_process').exec;
|
4 | var semver = require('semver');
|
5 | var format = require('util').format;
|
6 | var getTag = require('./getTag');
|
7 |
|
8 | var isPrerelease = function (v) {
|
9 | return semver.prerelease(v) !== null;
|
10 | };
|
11 | var isNotPrerelease = function (v) {
|
12 | return !isPrerelease(v);
|
13 | };
|
14 |
|
15 | module.exports = function getLatestError(name, version, options, callback) {
|
16 | if (process.env.PUBLISH_LATEST_DANGEROUSLY === 'true') {
|
17 | return callback(null, '$PUBLISH_LATEST_DANGEROUSLY override enabled.');
|
18 | }
|
19 | if (getTag() !== 'latest') {
|
20 | return callback(null, 'Non-latest dist-tag detected.');
|
21 | }
|
22 |
|
23 | return exec('npm info ' + name + ' versions --json --loglevel=info', function (err, json) {
|
24 | if (err) {
|
25 | if ((/^npm ERR! code E404$/m).test(err)) {
|
26 | return callback(null, 'v' + version + ' is the first version published.');
|
27 | }
|
28 | return callback([
|
29 | 'Error fetching package versions:',
|
30 | err
|
31 | ]);
|
32 | }
|
33 | var allVersions;
|
34 | try {
|
35 | allVersions = [].concat(JSON.parse(json));
|
36 | } catch (e) {
|
37 | return callback([
|
38 | 'Error parsing JSON from npm',
|
39 | e
|
40 | ]);
|
41 | }
|
42 |
|
43 | var versions = allVersions.filter(isNotPrerelease);
|
44 | if (versions.length === 0) {
|
45 | return callback(null, 'No non-prerelease versions detected.');
|
46 | }
|
47 |
|
48 | var max = semver.maxSatisfying(versions, '*');
|
49 | if (semver.eq(version, max)) {
|
50 | return callback([
|
51 | 'Attempting to publish already-published version v' + version + '.'
|
52 | ]);
|
53 | }
|
54 |
|
55 | var greater = semver.gtr(version, versions.join('||'));
|
56 | var prerelease = isPrerelease(version);
|
57 | if (!greater || prerelease) {
|
58 | var msg = prerelease
|
59 | ? format('Attempting to publish v%s as "latest", but it is a prerelease version.', version)
|
60 | : format('Attempting to publish v%s as "latest", but it is not later than v%s.', version, max);
|
61 | return callback([
|
62 | msg,
|
63 | '\nPossible Solutions:',
|
64 | '\t1) Provide a dist-tag: `npm publish --tag=backport`, for example',
|
65 | '\t2) Use the very dangerous override: `PUBLISH_LATEST_DANGEROUSLY=true npm publish`'
|
66 | ]);
|
67 | }
|
68 |
|
69 | return callback(null, format('v%s is later than v%s.', version, max));
|
70 | });
|
71 | };
|