Skip to content

Commit 00dc5af

Browse files
committed
Release 1.1.0: Sub-Module Support
1 parent aa2e3ef commit 00dc5af

File tree

4 files changed

+113
-22
lines changed

4 files changed

+113
-22
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<<<<<<< HEAD
21
# VsCode - Github-File-Folder-Url
32

43
VsCode Extension that gets a Github url with optional line selection for files and folders.
@@ -9,11 +8,16 @@ Usage: `Ctrl+Alt+Shift+G` gets url and line selection copies it to the clipboard
98

109
Usage: `Ctrl+Alt+Z` gets url for all open files and copies them to clipboard
1110

12-
## Install
11+
Full git sub-module support now included.
12+
13+
# Version History
14+
- `1.1.0:` Sub-Module Support
15+
- `1.0.0:` Initial Release
16+
17+
# Install
1318

1419
1. Within Visual Studio Code, open the command palette (`Ctrl-Shift-P` / `Cmd-Shift-P`)
1520
2. Type `install extension` and search for `Github-File-Folder-Url`
1621
=======
1722
# vscode-github-file-folder-url
1823
VsCode Extension that gets a Github url with optional line selection for files and folders.
19-
>>>>>>> 929ad2d5bef3745e96fd10f632d5f56eabdd06ce

extension.js

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ const copyPaste = require("copy-paste");
1010

1111
const extensionName = 'Github-File-Url';
1212

13+
const TYPE = {
14+
git_config: '.git/config',
15+
git_modules: '.gitmodules',
16+
};
1317

1418
// This method is called when your extension is activated
1519
// Your extension is activated the very first time the command is executed
@@ -43,7 +47,7 @@ function executeCommandAllTextEditors(commandName) {
4347
return;
4448
}
4549

46-
textEditors.forEach(p=> uniquePaths[p.fileName] = true);
50+
textEditors.forEach(p => uniquePaths[p.fileName] = true);
4751

4852
const allPaths = [];
4953
const allErrors = [];
@@ -55,7 +59,7 @@ function executeCommandAllTextEditors(commandName) {
5559
case 'success':
5660
{
5761
const url = result.url;
58-
const relativeFilePath = result.relativeFilePath;
62+
const relativeFilePath = result.relativePathFromGitRoot;
5963
const urlMarkdownLink = `[${relativeFilePath}](${url})`;
6064
allPaths.push(urlMarkdownLink);
6165
}
@@ -134,7 +138,7 @@ function executeCommand1(commandName, fileUri, pullLines) {
134138
case 'success':
135139
{
136140
const url = result.url;
137-
const relativeFilePath = result.relativeFilePath;
141+
const relativeFilePath = result.relativePathFromGitRoot;
138142
const urlMarkdownLink = `[${relativeFilePath}](${url})`;
139143
copyPaste.copy(urlMarkdownLink);
140144
}
@@ -175,27 +179,44 @@ Workspace Root: ${workspaceRootPath}`;
175179

176180
function generateGithubUrl(commandName, workspaceRootPath, filePath, lineSelection) {
177181
try {
178-
const parseResult = findAndParseConfig(workspaceRootPath);
182+
workspaceRootPath = workspaceRootPath.replace(/\\/g, '/'); // Flip subdir slashes on Windows
183+
filePath = filePath.replace(/\\/g, '/'); // Flip subdir slashes on Windows
184+
const parseResult = findAndParseConfig(filePath);
179185
if (!parseResult) {
180186
const errorMessage = `${extensionName} extension failed to find a Github config at the workspace folder or any of it's parent folders.
181187
Is this a Github repository?
182188
183-
Workspace Root: ${workspaceRootPath}`;
189+
Workspace Root: ${workspaceRootPath}
190+
Filepath: ${filePath}`;
184191
return {
185192
type: 'error',
186193
errorMessage,
187194
};
188195
}
189196
const config = parseResult.config;
190-
const cwd = parseResult.rootPath;
191-
const branch = gitBranch.sync(cwd);
197+
const rootPathForGitConfig = parseResult.rootPath;
198+
const branch = gitBranch.sync(rootPathForGitConfig);
192199
const remoteConfig = config[`branch "${branch}"`];
193200
const remoteName = remoteConfig && remoteConfig.remote ? remoteConfig.remote : 'origin';
194201
const finalConfig = config[`remote "${remoteName}"`];
195202
if (finalConfig) {
196-
const githubRootUrl = githubUrlFromGit(finalConfig.url);
197-
let relativeFilePath = filePath.substring(cwd.length).replace(/\\/g, '/'); // Flip subdir slashes on Windows
203+
let targetUrl = finalConfig.url;
204+
let targetPath = rootPathForGitConfig;
205+
for (const sub of parseResult.subModules) {
206+
if (filePath.search(sub.path) === 0) {
207+
targetUrl = sub.url;
208+
targetPath = sub.path;
209+
break;
210+
}
211+
}
212+
213+
const githubRootUrl = githubUrlFromGit(targetUrl);
214+
let relativePathFromGitRoot = filePath.substring(rootPathForGitConfig.length).replace(/\\/g, '/'); // Flip subdir slashes on Windows
215+
let relativeFilePath = filePath.substring(targetPath.length).replace(/\\/g, '/'); // Flip subdir slashes on Windows
198216
let url = `${githubRootUrl}/blob/${branch}${relativeFilePath}`;
217+
if (relativePathFromGitRoot[0] === '/') {
218+
relativePathFromGitRoot = relativePathFromGitRoot.slice(1);
219+
}
199220
if (relativeFilePath[0] === '/') {
200221
relativeFilePath = relativeFilePath.slice(1);
201222
}
@@ -214,12 +235,14 @@ Workspace Root: ${workspaceRootPath}`;
214235
type: 'success',
215236
url,
216237
relativeFilePath,
238+
relativePathFromGitRoot,
217239
}
218240
} else {
219241
let errorMessage = `${extensionName} extension failed to find a remote config for "${remoteName}" in branch "${branch}".
220242
Is this a Github repository?
221243
222-
Workspace Root: ${workspaceRootPath}`;
244+
Workspace Root: ${workspaceRootPath}
245+
Filepath: ${filePath}`;
223246
return {
224247
type: 'error',
225248
errorMessage,
@@ -238,26 +261,90 @@ Workspace Root: ${workspaceRootPath}`;
238261
}
239262
}
240263

264+
const reSubModulePuller = /"([^"]*)"/g;
265+
241266
function findAndParseConfig(rootPath) {
242-
function intParseConfig(cwd) {
243-
let ret = parseConfig.sync({ cwd: cwd, path: '.git/config' });
267+
function intParseGitConfig(cwd) {
268+
let ret = parseConfig.sync({ cwd: cwd, path: TYPE.git_config });
269+
if (!(Object.keys(ret).length === 0 && ret.constructor === Object)) {
270+
return ret;
271+
}
272+
}
273+
function intParseModuleConfig(cwd) {
274+
let ret = parseConfig.sync({ cwd: cwd, path: TYPE.git_modules });
244275
if (!(Object.keys(ret).length === 0 && ret.constructor === Object)) {
245276
return ret;
246277
}
247278
}
248279

249280
rootPath = rootPath.replace(/\\/g, '/'); // Flip subdir slashes on Windows
250281
const pathParts = rootPath.split('/');
282+
let subModuleConfigs = [];
283+
let subModules = [];
251284
let stepsUp = 0;
252285
while (pathParts.length > 0) {
253286
let currentPath = pathParts.join('/');
254-
let config = intParseConfig(currentPath);
255-
if (config) {
256-
return {
287+
let gitConfig = intParseGitConfig(currentPath);
288+
function pullSubModules(subMeta) {
289+
const config = subMeta.config;
290+
const ret = [];
291+
for (const key in config) {
292+
const match1 = reSubModulePuller.exec(key);
293+
if (match1 && match1.length === 2) {
294+
const subConfig = config[key];
295+
const subUrl = subConfig.url;
296+
const modName = match1[1];
297+
const modFullpath = path.join(currentPath, modName).replace(/\\/g, '/');
298+
if (!subUrl) {
299+
console.warn(`subModule '${name}' at '${modFullpath}' is missing a url, it will be skipped`);
300+
} else {
301+
const metaInfo = {
302+
path: modFullpath,
303+
name: modName,
304+
url: subUrl,
305+
};
306+
subModules.push(metaInfo);
307+
ret.push(metaInfo);
308+
}
309+
}
310+
}
311+
return ret;
312+
}
313+
if (gitConfig) {
314+
315+
const pathMap = [];
316+
for (const sub of subModuleConfigs) {
317+
const subRoot = sub.path;
318+
// const fullModulePath = path.join(sub.)).replace(/\\/g, '/')
319+
// pathMap
320+
}
321+
322+
const rootMeta = {
323+
type: TYPE.git_config,
257324
rootPath: currentPath,
258-
config,
259-
stepsUp
325+
path: currentPath,
326+
config: gitConfig,
327+
stepsUp,
260328
};
329+
const subs = pullSubModules(rootMeta);
330+
rootMeta.subs = subs;
331+
332+
rootMeta.subModules = subModules;
333+
334+
return rootMeta;
335+
} else {
336+
let moduleConfig = intParseModuleConfig(currentPath);
337+
if (moduleConfig) {
338+
const subMeta = {
339+
type: TYPE.git_modules,
340+
path: currentPath,
341+
config: moduleConfig,
342+
stepsUp,
343+
};
344+
const subs = pullSubModules(subMeta);
345+
subMeta.subs = subs;
346+
subModuleConfigs.push(subMeta);
347+
}
261348
}
262349
stepsUp++;
263350
pathParts.pop();

images/icon.png

9.21 KB
Loading

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vscode-github-file-folder-url",
3-
"version": "1.0.0",
3+
"version": "1.1.6",
44
"publisher": "cycloware",
55
"displayName": "VsCode - Github-File-Folder-Url",
66
"description": "VsCode Extension that gets a Github url with optional line selection for files and folders.",
@@ -77,6 +77,6 @@
7777
"copy-paste": "1.3.0",
7878
"git-branch": "0.3.0",
7979
"github-url-from-git": "1.5.0",
80-
"parse-git-config": "1.1.0"
80+
"parse-git-config": "1.1.1"
8181
}
8282
}

0 commit comments

Comments
 (0)