-
Notifications
You must be signed in to change notification settings - Fork 100
/
Copy pathSource.js
134 lines (124 loc) · 6.94 KB
/
Source.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var url = require('url');
var semver = require('semver');
var nijs = require('nijs');
var inherit = require('nijs/lib/ast/util/inherit.js').inherit;
var base64js = require('base64-js');
/**
* Creates a new source instance. This function should never be used directly,
* instead use: Source.constructSource to construct a source object.
*
* @class Source
* @extends NixASTNode
* @classdesc Represents a file that is obtained from an external source
*
* @constructor
* @param {String} baseDir Directory in which the referrer's package.json configuration resides
* @param {String} dependencyName Name of the dependency
* @param {String} versionSpec Version specifier of the Node.js package to fetch
*/
function Source(baseDir, dependencyName, versionSpec) {
this.baseDir = baseDir;
this.dependencyName = dependencyName;
this.versionSpec = versionSpec;
}
/* Source inherits from NixASTNode */
inherit(nijs.NixASTNode, Source);
/**
* Constructs a specific kind of source by inspecting the version specifier.
*
* @param {String} registryURL URL of the NPM registry
* @param {?String} registryAuthToken Auth token for private NPM registry
* @param {String} baseDir Directory in which the referrer's package.json configuration resides
* @param {String} outputDir Directory in which the nix expression will be written
* @param {String} dependencyName Name of the dependency
* @param {String} versionSpec Version specifier of the Node.js package to fetch
* @param {Boolean} stripOptionalDependencies When enabled, the optional
* dependencies are stripped from the regular dependencies in the NPM registry
*/
Source.constructSource = function(registryURL, registryAuthToken, baseDir, outputDir, dependencyName, versionSpec, stripOptionalDependencies) {
// Load modules here, to prevent cycles in the include process
var GitSource = require('./GitSource.js').GitSource;
var HTTPSource = require('./HTTPSource.js').HTTPSource;
var LocalSource = require('./LocalSource.js').LocalSource;
var NPMRegistrySource = require('./NPMRegistrySource.js').NPMRegistrySource;
var parsedVersionSpec = semver.validRange(versionSpec, true);
var parsedUrl = url.parse(versionSpec);
if(parsedVersionSpec !== null) { // If the version is valid semver range, fetch the package from the NPM registry
return new NPMRegistrySource(baseDir, dependencyName, parsedVersionSpec, registryURL, registryAuthToken, stripOptionalDependencies);
} else if(parsedUrl.protocol == "github:") { // If the version is a GitHub repository, compose the corresponding Git URL and do a Git checkout
return new GitSource(baseDir, dependencyName, GitSource.composeGitURL("git://github.com", parsedUrl));
} else if(parsedUrl.protocol == "gist:") { // If the version is a GitHub gist repository, compose the corresponding Git URL and do a Git checkout
return new GitSource(baseDir, dependencyName, GitSource.composeGitURL("https://gist.github.com", parsedUrl));
} else if(parsedUrl.protocol == "bitbucket:") { // If the version is a Bitbucket repository, compose the corresponding Git URL and do a Git checkout
return new GitSource(baseDir, dependencyName, GitSource.composeGitURL("git://bitbucket.org", parsedUrl));
} else if(parsedUrl.protocol == "gitlab:") { // If the version is a Gitlab repository, compose the corresponding Git URL and do a Git checkout
return new GitSource(baseDir, dependencyName, GitSource.composeGitURL("https://gitlab.com", parsedUrl));
} else if(typeof parsedUrl.protocol == "string" && parsedUrl.protocol.substr(0, 3) == "git") { // If the version is a Git URL do a Git checkout
return new GitSource(baseDir, dependencyName, versionSpec);
} else if(parsedUrl.protocol == "http:" || parsedUrl.protocol == "https:") { // If the version is an HTTP URL do a download
return new HTTPSource(baseDir, dependencyName, versionSpec);
} else if(versionSpec.match(/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9\.]+[#[a-zA-Z0-9_\-]+]?$/)) { // If the version is a GitHub repository, compose the corresponding Git URL and do a Git checkout
return new GitSource(baseDir, dependencyName, "git://github.com/"+versionSpec);
} else if(parsedUrl.protocol == "file:") { // If the version is a file URL, simply compose a Nix path
return new LocalSource(baseDir, dependencyName, outputDir, parsedUrl.path);
} else if(versionSpec.substr(0, 3) == "../" || versionSpec.substr(0, 2) == "~/" || versionSpec.substr(0, 2) == "./" || versionSpec.substr(0, 1) == "/") { // If the version is a path, simply compose a Nix path
return new LocalSource(baseDir, dependencyName, outputDir, versionSpec);
} else { // In all other cases, just try the registry. Sometimes invalid semver ranges are encountered or a tag has been provided (e.g. 'latest', 'unstable')
return new NPMRegistrySource(baseDir, dependencyName, versionSpec, registryURL, registryAuthToken, stripOptionalDependencies);
}
};
/**
* Fetches the package metadata from the external source.
*
* @method
* @param {function(String)} callback Callback that gets invoked when the work
* is done. In case of an error, it will set the first parameter to contain
* an error message.
*/
Source.prototype.fetch = function(callback) {
callback("fetch() is not implemented, please use a prototype that inherits from Source");
};
/**
* Takes a dependency object from a lock file and converts it into a source object.
*
* @param {Object} dependencyObj Dependency object from the lock file
* @param {function(String)} callback Callback that gets invoked when the work
* is done. In case of an error, it will set the first parameter to contain
* an error message.
*/
Source.prototype.convertFromLockedDependency = function(dependencyObj, callback) {
callback("convertFromLockedDependency() is not implemented, please use a prototype that inherits from Source");
};
/**
* Converts NPM's integrity strings that have the following format:
* <algorithm>-<base64 hash> to a hash representation that Nix understands.
*
* @method
* @param {String} integrity NPM integrity string
*/
Source.prototype.convertIntegrityStringToNixHash = function(integrity) {
if(integrity.substr(0, 5) === "sha1-") {
var hash = base64js.toByteArray(integrity.substring(5));
this.hashType = "sha1";
this.sha1 = new Buffer(hash).toString('hex');
} else if(integrity.substr(0, 7) === "sha512-") {
this.hashType = "sha512";
this.sha512 = integrity.substring(7);
} else {
throw "Unknown integrity string: "+integrity;
}
};
/**
* @see NixASTNode#toNixAST
*/
Source.prototype.toNixAST = function() {
if(!this.config.name){
console.log("name is missing:", this.config);
}
return {
name: this.config.name.replace("@", "_at_").replace("/", "_slash_"), // Escape characters from scoped package names that aren't allowed
packageName: this.config.name,
version: this.config.version
};
};
exports.Source = Source;