UNPKG

9.43 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var Fs = require("fs-extra");
4var path_1 = require("path");
5var git_1 = require("./git");
6var paths_1 = require("./paths");
7var utils_1 = require("./utils");
8// Like git-submodule-add, but will ensure that we're currently at root and will detach HEAD
9function addSubmodule(name, url) {
10 if (!name) {
11 throw TypeError('Submodule name must be provided');
12 }
13 if (!url) {
14 throw TypeError('Submodule URL must be provided');
15 }
16 {
17 var isRoot = git_1.Git.rootHash() === git_1.Git(['rev-parse', 'HEAD']);
18 if (!isRoot) {
19 throw Error('Use `$ tortilla step edit --root` first');
20 }
21 }
22 git_1.Git.print(['submodule', 'add', url, name]);
23 var cwd = resolveSubmodulePath(name);
24 var sha1 = git_1.Git(['rev-parse', 'HEAD'], { cwd: cwd });
25 git_1.Git.print(['checkout', sha1], { cwd: cwd });
26 git_1.Git(['add', '.gitmodules', name]);
27}
28// Will remove the submodule completely, even from the git-registry. This command doesn't
29// exist on git and it can be very useful
30function removeSubmodule(name) {
31 if (!name) {
32 throw TypeError('Submodule name must be provided');
33 }
34 {
35 var isRoot = git_1.Git.rootHash() === git_1.Git(['rev-parse', 'HEAD']);
36 if (!isRoot) {
37 throw Error('Use `$ tortilla step edit --root` first');
38 }
39 }
40 git_1.Git.print(['submodule', 'deinit', '-f', name]);
41 Fs.removeSync(resolveSubmodulePath(name));
42 Fs.remove(path_1.resolve(paths_1.Paths.git.modules, name));
43 git_1.Git(['config', '--file=.gitmodules', '--remove-section', "submodule." + name]);
44 // Adding to stage is necessary before we can clean the cache
45 git_1.Git(['add', '.gitmodules']);
46 // This will also stage the submodule
47 git_1.Git.print(['rm', '--cached', '-rf', name]);
48}
49// Will run git-submodule-update --init, and it will remove deleted files from stage if
50// pointed object doesn't exist in submodule's remote. This behavior is much more expected
51// and less confusing rather than seeing that everything was deleted for an odd reason.
52function updateSubmodule(name) {
53 if (!name) {
54 throw TypeError('Submodule name must be provided');
55 }
56 git_1.Git.print(['submodule', 'update', '--init', name]);
57 var cwd = resolveSubmodulePath(name);
58 // Will be effective only if hash doesn't exist
59 git_1.Git(['reset', '.'], { cwd: cwd });
60 git_1.Git(['checkout', '.'], { cwd: cwd });
61}
62// In other words, this will 'unclone' the submodule, but will keep it initialized. This is
63// reliable method to get away from messy situations with submodules, so whenever you don't know
64// what to do, run this command.
65function resetSubmodule(name) {
66 if (!name) {
67 throw TypeError('Submodule name must be provided');
68 }
69 var cwd = resolveSubmodulePath(name);
70 Fs.removeSync(cwd);
71 git_1.Git.print(['checkout', cwd]);
72}
73function fetchSubmodule(name) {
74 if (!name) {
75 throw TypeError('Submodule name must be provided');
76 }
77 if (!isSubmoduleUpdated(name)) {
78 throw Error("Submodule is not updated! Run \"$ tortilla submodule update " + name + "\"");
79 }
80 var cwd = resolveSubmodulePath(name);
81 git_1.Git.print(['fetch', 'origin', '--tags', '-f'], { cwd: cwd });
82}
83// This will check out the specified submodule to provided ref. It will also guide you through
84// with some detailed instructions if you should do things beforehand, this can prevent a lot of
85// potential issues and confusion.
86function checkoutSubmodule(name, ref) {
87 if (!name) {
88 throw TypeError('Submodule name must be provided');
89 }
90 if (!ref) {
91 throw TypeError('Submodule ref must be provided');
92 }
93 {
94 var isRoot = git_1.Git.rootHash() === git_1.Git(['rev-parse', 'HEAD']);
95 if (!isRoot) {
96 throw Error('Command must run in root! Run "$ tortilla step edit --root"');
97 }
98 }
99 if (!isSubmoduleUpdated(name)) {
100 throw Error("Submodule is not updated! Run \"$ tortilla submodule update " + name + "\"");
101 }
102 var cwd = resolveSubmodulePath(name);
103 try {
104 git_1.Git(['rev-parse', ref], { cwd: cwd });
105 }
106 catch (e) {
107 throw Error("git-ref " + ref + " doesn't exist! Run \"$ tortilla submodule fetch " + name + "\"");
108 }
109 git_1.Git.print(['checkout', ref], { cwd: cwd });
110 git_1.Git.print(['add', cwd]);
111}
112function isSubmoduleUpdated(name) {
113 if (!name) {
114 throw TypeError('Submodule name must be provided');
115 }
116 // Fetch most recent changes if already initialized
117 return (Fs.existsSync(path_1.resolve(paths_1.Paths.git.modules, name)) &&
118 Fs.existsSync(resolveSubmodulePath(name) + "/.git"));
119}
120function resolveSubmodulePath(name, relativePath) {
121 if (relativePath === void 0) { relativePath = ''; }
122 var absolutePath = path_1.resolve(utils_1.Utils.cwd(), name, relativePath);
123 if (!Fs.existsSync(absolutePath)) {
124 throw Error("Submodule folder \"" + name + "\" doesn't exist");
125 }
126 return absolutePath;
127}
128function listSubmodules() {
129 var root = git_1.Git.root();
130 if (!root) {
131 return [];
132 }
133 var configData;
134 try {
135 configData = git_1.Git([
136 'config', '--file', '.gitmodules', '--name-only', '--get-regexp', 'path',
137 ]);
138 // No submodules exit
139 }
140 catch (e) {
141 return [];
142 }
143 return configData.split('\n').map(function (submodule) {
144 return submodule.split('.')[1];
145 });
146}
147function listSubmodulesUrls(whiteList) {
148 if (whiteList === void 0) { whiteList = []; }
149 return git_1.Git([
150 'config', '--file', '.gitmodules', '--get-regexp', 'url',
151 ]).split('\n')
152 .filter(Boolean)
153 .map(function (line) {
154 var match = line.match(/^submodule\.([^\.]+)\.url\s(.+)$/);
155 if (!match) {
156 return;
157 }
158 var submodule = match[1];
159 var url = match[2];
160 if (!whiteList.length || whiteList.includes(submodule)) {
161 return url;
162 }
163 })
164 .filter(Boolean);
165}
166function isSubmodule() {
167 var root = git_1.Git.root();
168 if (!root) {
169 return false;
170 }
171 // If the directory one level up the root is a git project then it means that
172 // the current directory is a git project as well
173 try {
174 // This command should only work if we're in a git project
175 return !!git_1.Git(['rev-parse', '--show-toplevel'], {
176 cwd: path_1.resolve(root, '..'),
177 });
178 }
179 catch (e) {
180 return false;
181 }
182}
183function getRemoteSubmoduleName(remote) {
184 return remote
185 .split('/')
186 .pop()
187 .split('.')
188 .shift();
189}
190function getLocalSubmoduleName(givenPath) {
191 if (!givenPath) {
192 return '';
193 }
194 var givenPackPath = paths_1.Paths.resolveProject(givenPath).npm.package;
195 var givenPackName = JSON.parse(Fs.readFileSync(givenPackPath).toString()).name;
196 var submoduleName = listSubmodules().find(function (name) {
197 var submodulePath = utils_1.Utils.cwd() + "/" + name;
198 var submodulePackPath = paths_1.Paths.resolveProject(submodulePath).npm.package;
199 var submodulePackName = JSON.parse(Fs.readFileSync(submodulePackPath).toString()).name;
200 return submodulePackName === givenPackName;
201 });
202 return submoduleName || '';
203}
204// Will get the path of the development sub-repo
205function getSubmoduleCwd(name) {
206 var configLine = git_1.Git([
207 'config', '--file', '.gitmodules', '--get-regexp', "submodule." + name + ".url",
208 ]);
209 if (!configLine) {
210 return;
211 }
212 var relativePath = configLine.split(' ')[1];
213 return path_1.resolve(utils_1.Utils.cwd(), relativePath);
214}
215// Gets data regards specified submodules from git's objects tree
216function getSubmodulesFSNodes(_a) {
217 var _b = _a === void 0 ? {
218 cwd: utils_1.Utils.cwd(),
219 } : _a, whitelist = _b.whitelist, blacklist = _b.blacklist, revision = _b.revision, cwd = _b.cwd;
220 if (typeof revision === 'undefined') {
221 revision = git_1.Git(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: cwd });
222 }
223 return git_1.Git(['ls-tree', revision], { cwd: cwd })
224 // Each line represents a node
225 .split('\n')
226 // Map splits into informative jsons
227 .map(function (line) {
228 // Each split in the output represents different data
229 var _a = line.split(/\s+/), mode = _a[0], type = _a[1], hash = _a[2], file = _a[3];
230 return { mode: mode, type: type, hash: hash, file: file };
231 })
232 // Filter submodules which are included in the list
233 .filter(function (_a) {
234 var type = _a.type, file = _a.file;
235 return type === 'commit' &&
236 (!whitelist || whitelist.includes(file)) &&
237 (!blacklist || !blacklist.includes(file));
238 });
239}
240exports.Submodule = {
241 add: addSubmodule,
242 remove: removeSubmodule,
243 reset: resetSubmodule,
244 fetch: fetchSubmodule,
245 update: updateSubmodule,
246 checkout: checkoutSubmodule,
247 isUpdated: isSubmoduleUpdated,
248 resolvePath: resolveSubmodulePath,
249 list: listSubmodules,
250 urls: listSubmodulesUrls,
251 isOne: isSubmodule,
252 getRemoteName: getRemoteSubmoduleName,
253 getLocalName: getLocalSubmoduleName,
254 getCwd: getSubmoduleCwd,
255 getFSNodes: getSubmodulesFSNodes,
256};
257//# sourceMappingURL=submodule.js.map
\No newline at end of file