1 |
|
2 | (function() {
|
3 | var autocode, fs, install, mkdirp, path, request, semver, untar, userHome, zlib;
|
4 |
|
5 | autocode = require('../autocode');
|
6 |
|
7 | fs = require('fs');
|
8 |
|
9 | mkdirp = require('mkdirp');
|
10 |
|
11 | path = require('path');
|
12 |
|
13 | request = require('sync-request');
|
14 |
|
15 | semver = require('semver');
|
16 |
|
17 | untar = require('untar.js');
|
18 |
|
19 | userHome = require('user-home');
|
20 |
|
21 | zlib = require('zlib');
|
22 |
|
23 | install = function(opts) {
|
24 | var access_token_url, config_resp, config_url, headers, host, j, len, module_is_lastest, module_name, module_parse, module_path, module_version, project, release, release_i, release_resp, release_url, release_version, releases, tag_name, tarball, tarball_response, tarball_url;
|
25 | host = 'github.com';
|
26 | if (typeof opts === 'object' && opts.name) {
|
27 | module_name = opts.name;
|
28 | }
|
29 | if (typeof opts === 'object' && opts.version) {
|
30 | module_version = opts.version;
|
31 | } else if (module_name.match('@')) {
|
32 | module_parse = module_name.split('@');
|
33 | module_name = module_parse[0];
|
34 | module_version = module_parse[1];
|
35 | } else {
|
36 | module_version = 'latest';
|
37 | }
|
38 | if (!module_name) {
|
39 | throw new Error("Module Name is required for `autocode install`.");
|
40 | }
|
41 | console.log(("Loading module (" + module_name + ")...").blue);
|
42 | headers = {
|
43 | 'User-Agent': 'Autocode <support@autocode.run> (https://autocode.run/autocode)'
|
44 | };
|
45 | access_token_url = '';
|
46 | if (process.env.GITHUB_ACCESS_TOKEN) {
|
47 | access_token_url += "?access_token=" + process.env.GITHUB_ACCESS_TOKEN;
|
48 | }
|
49 | if (module_version === 'latest') {
|
50 | module_is_lastest = true;
|
51 | release_url = "https://api.github.com/repos/" + module_name + "/releases/latest" + access_token_url;
|
52 | release_resp = request('get', release_url, {
|
53 | headers: headers,
|
54 | allowRedirectHeaders: ['User-Agent']
|
55 | });
|
56 | if (release_resp.statusCode !== 200) {
|
57 | throw new Error("Module (" + module_name + ") does not exist on GitHub.");
|
58 | }
|
59 | release = JSON.parse(release_resp.body);
|
60 | if (!release) {
|
61 | throw new Error("Unable to locate generator (" + name + ").");
|
62 | }
|
63 | module_version = semver.clean(release.tag_name);
|
64 | tag_name = release.tag_name;
|
65 | console.log(("Latest version is " + release.tag_name + ".").green);
|
66 | } else {
|
67 | module_is_lastest = false;
|
68 | release_url = "https://api.github.com/repos/" + module_name + "/releases" + access_token_url;
|
69 | release_resp = request('get', release_url, {
|
70 | headers: headers,
|
71 | allowRedirectHeaders: ['User-Agent']
|
72 | });
|
73 | if (release_resp.statusCode !== 200) {
|
74 | throw new Error("Module (" + module_name + ") does not exist on GitHub.");
|
75 | }
|
76 | releases = JSON.parse(release_resp.body);
|
77 | if (!releases) {
|
78 | throw new Error("Unable to locate generator (" + name + ").");
|
79 | }
|
80 | release_i = 0;
|
81 | for (j = 0, len = releases.length; j < len; j++) {
|
82 | release = releases[j];
|
83 | release_version = semver.clean(release.tag_name);
|
84 | if (semver.satisfies(release_version, module_version)) {
|
85 | if (release_i === 0) {
|
86 | module_is_lastest = true;
|
87 | }
|
88 | module_version = semver.clean(release.tag_name);
|
89 | tag_name = release.tag_name;
|
90 | break;
|
91 | }
|
92 | release_i++;
|
93 | }
|
94 | if (!tag_name) {
|
95 | throw new Error("Unable to find version (" + module_version + ") for module (" + module_name + ").");
|
96 | }
|
97 | console.log(("Found version (" + module_version + ") with tag (" + tag_name + ").").green);
|
98 | }
|
99 | if (opts.force !== true) {
|
100 | config_url = "https://api.github.com/repos/" + module_name + "/contents/.autocode/config.yml" + access_token_url + "&ref=" + tag_name;
|
101 | config_resp = request('get', config_url, {
|
102 | headers: headers,
|
103 | allowRedirectHeaders: ['User-Agent']
|
104 | });
|
105 | if (config_resp.statusCode !== 200) {
|
106 | throw new Error("Module (" + module_name + ") has not implemented Autocode. Use -f to install anyways.");
|
107 | }
|
108 | }
|
109 | tarball_url = "" + release.tarball_url + access_token_url;
|
110 | console.log(("Downloading from: " + tarball_url).bold);
|
111 | tarball_response = request('get', tarball_url, {
|
112 | headers: headers,
|
113 | allowRedirectHeaders: ['User-Agent']
|
114 | });
|
115 | if (tarball_response.statusCode !== 200) {
|
116 | throw new Error("Unable to download module (" + module_name + ").");
|
117 | }
|
118 | tarball = zlib.gunzipSync(tarball_response.body);
|
119 | if (!tarball) {
|
120 | throw new Error("Unable to unzip module (" + module_name + ").");
|
121 | }
|
122 | module_path = path.normalize(userHome + "/.autocode/module/" + host + "/" + module_name + "/" + module_version);
|
123 | if (fs.existsSync(module_path) && opts.ignoreOverwrite) {
|
124 | return {
|
125 | name: module_name,
|
126 | version: module_version
|
127 | };
|
128 | }
|
129 | untar.untar(tarball).forEach(function(file) {
|
130 | var buffer, file_path, filename, i, link_path;
|
131 | filename = file.filename.split('/').slice(1).join('/');
|
132 | file_path = path.dirname(filename);
|
133 | mkdirp.sync(module_path + "/" + file_path);
|
134 | buffer = new Buffer(file.fileData.length);
|
135 | i = 0;
|
136 | while (i < file.fileData.length) {
|
137 | buffer.writeUInt8(file.fileData[i], i);
|
138 | i++;
|
139 | }
|
140 | fs.writeFileSync(module_path + "/" + filename, buffer);
|
141 | if (module_is_lastest) {
|
142 | link_path = path.normalize(userHome + "/.autocode/module/" + host + "/" + module_name + "/latest");
|
143 | if (fs.existsSync(link_path)) {
|
144 | fs.unlinkSync(link_path);
|
145 | }
|
146 | return fs.symlinkSync(module_path, link_path);
|
147 | }
|
148 | });
|
149 | project = new autocode(module_path);
|
150 | project.update();
|
151 | project.build({
|
152 | skipGeneration: true
|
153 | });
|
154 | console.log(("Successfully installed " + module_name + " at: " + module_path).green);
|
155 | return {
|
156 | name: module_name,
|
157 | version: module_version
|
158 | };
|
159 | };
|
160 |
|
161 | module.exports = install;
|
162 |
|
163 | }).call(this);
|