UNPKG

7.37 kBJavaScriptView Raw
1(function () {
2 var path = require('path'),
3 fs = require('fs-extra'),
4 glob = require('glob'),
5 semver = require('semver'),
6 request = require('sync-request'),
7 AdmZip = require('adm-zip'),
8 sync = require('child_process').execSync,
9 kew = require('kew');
10
11 var cdnUrl = process.env.npm_config_sonarrunner_cdnurl || process.env.SONARRUNNER_CDNURL,
12 cdnDir = process.env.npm_config_sonarrunner_cdndir || process.env.SONARRUNNER_CDNDIR,
13 destination = 'lib',
14 validExit = false;
15
16 /** Handle event handling when an exit occurs. */
17 process.on('exit', function () {
18 if (!validExit) {
19 console.log('Install exited unexpectedly');
20 exit(1)
21 }
22 });
23
24 /**
25 * Handles a valid exit.
26 * @param code The exit code.
27 */
28 function exit(code) {
29 validExit = true;
30 process.exit(code || 0)
31 }
32
33 /**
34 * Indicates if sonar-runner is available.
35 * @return <code>true</code> if available, else <code>false</code>.
36 */
37 function isSonarInstalled() {
38 return isSonarInstalledGlobally() || isSonarInstalledLocally();
39 }
40
41 /**
42 * Indicates if sonar-runner is available globally (ie on the command-line)
43 * @return <code>true</code> if available, else <code>false</code>.
44 */
45 function isSonarInstalledGlobally() {
46 try {
47 sync('sonar-runner --version', {encoding: 'utf8', stdio: ['ignore', 'ignore', 'ignore']});
48 console.log('Sonar-runner is already installed on the path`.');
49 exit(0);
50 } catch (e) {
51 console.log('Sonar-runner command [sonar-runner] could not be found on the path, checking locally...');
52 return false;
53 }
54 }
55
56 /**
57 * Indicates if sonar-runner is available locally (in the lib dir)
58 * @return <code>true</code> if available, else <code>false</code>.
59 */
60 function isSonarInstalledLocally() {
61 var libDir = path.join(__dirname, 'lib'),
62 extension = (/^win/.test(process.platform) ? '.bat' : '');
63
64 if (fs.existsSync(libDir)) {
65 glob.sync('**/bin/sonar-runner' + extension, {cwd: libDir, root: '/'}).forEach(function (file) {
66 console.log('Sonar-runner is already installed locally.');
67 exit(0);
68 });
69 }
70 console.log('Sonar-runner command [sonar-runner] could not be found locally either.');
71 return false;
72 }
73
74 /**
75 * Copy the latest sonar-runner from the given cdn dir.
76 * @param cdnDir The cdn dir.
77 * @return destination The location where the latest sonar-runner is copied to.
78 * @throws error If no sonar-runner can be found on the cdn.
79 */
80 function copyLatestVersion(cdnDir) {
81 var latestAvailableVersion, latestFileName;
82 glob.sync('sonar-runner*.zip', {cwd: cdnDir, root: '/'}).forEach(function (file) {
83 var match = /sonar-runner.*(\d)\.(\d)\.?(\d?).zip/.exec(file);
84 if (match) { // convert to semver
85 var currentVersion = (match[1] + '.' + match[2] + '.' + (match[3] ? match[3] : '0'));
86 if (latestAvailableVersion === undefined) {
87 latestAvailableVersion = currentVersion;
88 latestFileName = file;
89 } else if (semver.gt(currentVersion, latestAvailableVersion)) {
90 latestAvailableVersion = currentVersion;
91 latestFileName = file;
92 }
93 }
94 src = cdnDir + path.sep + latestFileName;
95 });
96
97 if (latestFileName !== undefined) {
98 var source = cdnDir + path.sep + latestFileName,
99 destination = path.join('.tmp', latestFileName);
100
101 if (destination) {
102 fs.copySync(source, destination, {replace: true});
103 return destination
104 }
105 } else {
106 console.error('Could not find any sonar-runner on the specified CDN.');
107 return;
108 }
109 }
110
111 /**
112 * Fetch the cdn release of sonar-runner from nexus.
113 * @param cdnDir The cdn url.
114 * @return destination The location where the cdn sonar-runner is copied to.
115 */
116 function fetchCdnVersion(cdnUrl) {
117 var response = request('GET', cdnUrl + path.sep + 'sonar-runner-dist.zip');
118 var destination = path.join('.tmp', 'sonar-runner-dist.zip');
119 fs.mkdirsSync('.tmp', '0775');
120 fs.writeFileSync(destination, response.getBody(), {replace: true});
121 return destination;
122 }
123
124 /**
125 * Fetch the latest release of sonar-runner from nexus.
126 * @return destination The location where the latest sonar-runner is copied to.
127 */
128 function fetchLatestVersion() {
129 var response = request('GET', 'https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.codehaus.sonar.runner&a=sonar-runner-dist&v=LATEST&p=zip');
130 var destination = path.join('.tmp', 'sonar-runner-dist.latest.zip');
131 fs.mkdirsSync('.tmp', '0775');
132 fs.writeFileSync(destination, response.getBody(), {replace: true});
133 return destination;
134 }
135
136 /** Extract the latest release of sonar-runner to the lib directory. */
137 function extractLatestVersion(source) {
138 var deferred = kew.defer();
139 try {
140 fs.mkdirsSync(destination, '0775');
141 fs.chmodSync(destination, '0775');
142
143 // unzip file
144 var zip = new AdmZip(source);
145 zip.extractAllTo(destination, true);
146
147 // fix execution rights
148 glob.sync('**/bin/sonar-runner*', {cwd: destination, root: '/'}).forEach(function (file) {
149 fs.chmodSync(destination + path.sep + file, '0777');
150 });
151
152 deferred.resolve(destination)
153 } catch (err) {
154 console.error('Error extracting zip');
155 exit(1);
156 }
157 return deferred.promise
158 }
159
160 // 1. check if a cdn url has been specified
161 if (!isSonarInstalled()) {
162 var pkg;
163 if (cdnUrl) {
164 // 2. copy latest version
165 pkg = fetchCdnVersion(cdnUrl);
166 console.log('Fetching sonar-runner from CDN url [' + cdnUrl + '.');
167 } else if(cdnDir) {
168 // 3. fetch cdn version
169 pkg = copyLatestVersion(cdnDir);
170 console.log('Fetching sonar-runner from CDN dir [' + cdnDir + '.');
171 } else {
172 console.log('No CDN url or directory have been specified.');
173 console.log('Usage: either specify property sonarrunner_cdnurl/sonarrunner_cdndir in .npmrc or define it as a environment variable as SONARRUNNER_CDNURL/SONARRUNNER_CDNDIR.')
174 }
175
176 if (!pkg) { // 4. if no version is copied or something went wrong, try to fetch it from remote.
177 try {
178 console.log('Using remote location to fetch sonar-runner.');
179 pkg = fetchLatestVersion();
180 } catch (e) {
181 console.error('Could not download the latest version of sonar-runner from the remote repository due to the following error [' + e + '].');
182 exit(1);
183 }
184 }
185 // 5. make it available by extracting it.
186 extractLatestVersion(pkg);
187 }
188
189 exit(0);
190
191
192})();