Skip to content

Commit e80e70a

Browse files
committed
Add a way to check if git is configured or not.
- If it is not configured, you can configure it by sending path of git installation directory.
1 parent f4e8427 commit e80e70a

File tree

6 files changed

+196
-22
lines changed

6 files changed

+196
-22
lines changed

modules/git_functions.js

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
const utils = require('./utils');
22
const { spawn } = require('child_process');
3+
const commandExists = require('command-exists');
4+
const {stat} = require('fs');
35

46
let showAllLogs = false;
57

@@ -38,9 +40,58 @@ let git = {
3840
abortMerge,
3941
testGit,
4042
searchForHash,
41-
searchForCommitMessage
43+
searchForCommitMessage,
44+
getSettings
4245
};
4346

47+
let gitExecutablePath = 'git';
48+
49+
function getSettings({req, res}) {
50+
// 1. get git path from local storage.
51+
// 2a. if git path, check if the command exists.
52+
// 2b. if not git path, check if git exists in the PATH
53+
// 3. Either local storage git path OR git in PATH must exist.
54+
55+
let reqBody = req.body;
56+
let gitFnName = reqBody && reqBody.gitExecutablePath ? reqBody.gitExecutablePath + '/git.exe' : 'git';
57+
58+
gitFnName = gitFnName.replace(/\\/g, '/'); // replace back slashes with forward slashes
59+
60+
61+
if(gitFnName === 'git') {
62+
commandExists(gitFnName, callback);
63+
}
64+
else {
65+
stat(gitFnName, callback)
66+
}
67+
68+
return;
69+
70+
function callback(err, exists) {
71+
if(!exists) {
72+
sendResponse(res, {
73+
errorCode: 1,
74+
msg: 'I could not find GIT',
75+
description: 'You have two options here.. Add your git installation directory OR Add git to your PATH.'
76+
});
77+
return;
78+
}
79+
80+
setGitFn(gitFnName);
81+
sendResponse(res, {
82+
msg: 'Everything is fine'
83+
});
84+
};
85+
}
86+
87+
function setGitFn(gitFnName) {
88+
gitExecutablePath = gitFnName;
89+
}
90+
91+
function getGitFn() {
92+
return gitExecutablePath;
93+
}
94+
4495
function searchForCommitMessage({req, res, repo}) {
4596
return logRepo({ req, res, repo, options: {
4697
searchFor: 'commitmessage',
@@ -305,7 +356,6 @@ function getLocalProgressStatus(repo) {
305356
// no way yet to see stash in progress.
306357
// we'll detect these by checking UU on file status.
307358
return Promise.all([rebaseHeadPromise, mergeHeadPromise, revertHeadPromise, interactiveRebaseHeadPromise]).then((heads)=> {
308-
console.log('heads = ' + heads);
309359
if(heads[0] || heads[1] || heads[2]) {
310360
// there is something in progress!
311361
if(heads[0]) {
@@ -419,8 +469,6 @@ function unstageFile({req, res, repo}) {
419469

420470
gitOptions.push(fileName);
421471

422-
console.log(gitOptions);
423-
424472
const child = spawnGitProcess(repo, gitOptions);
425473
redirectIO(child, req, res);
426474
}
@@ -440,8 +488,6 @@ function stageFile({req, res, repo}) {
440488

441489
gitOptions.push(fileName);
442490

443-
console.log(gitOptions);
444-
445491
const child = spawnGitProcess(repo, gitOptions);
446492
redirectIO(child, req, res);
447493
}
@@ -512,8 +558,10 @@ function getCommit(options) {
512558
}
513559

514560
function spawnGitProcess(repo, processOptions) {
515-
// console.log('path = ' + utils.decodePath(repo));
516-
return spawn('git', processOptions, {
561+
if(showAllLogs) {
562+
console.log('git arguments', processOptions);
563+
}
564+
return spawn(gitExecutablePath, processOptions, {
517565
cwd: _getCwd(repo),
518566
stdio: [0, 'pipe', 'pipe']
519567
});
@@ -548,7 +596,7 @@ function logRepo3({repo, req, res}) {
548596
let logFormat = `--format=format:%H%n%an%n%ae%n%aD%n%s%n%P`;
549597
let logArgs = ['log', '-n 100', logFormat, '--branches'];
550598

551-
const child = spawn('git', logArgs, {
599+
const child = spawn(gitExecutablePath, logArgs, {
552600
cwd: utils.getCheckoutsDir() + '/' + repo,
553601
stdio: [0, 'pipe', 'pipe']
554602
});
@@ -604,9 +652,7 @@ log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset)
604652
logArgs.push('--skip=' + ((page - 1) * commitsInOnePageCount));
605653
}
606654

607-
console.log(logArgs);
608-
609-
const child = spawn('git', logArgs, {
655+
const child = spawn(gitExecutablePath, logArgs, {
610656
cwd: _getCwd(repo),
611657
stdio: [0, 'pipe', 'pipe']
612658
});
@@ -625,7 +671,7 @@ function clone({req, res}) {
625671
cloneOptions.push(cloneSubdirectoryName);
626672
}
627673

628-
const child = spawn('git', cloneOptions, {
674+
const child = spawn(gitExecutablePath, cloneOptions, {
629675
cwd: destinationDir,
630676
stdio: [0, 'pipe', 'pipe']
631677
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"express": "~4.15.5",
1515
"jade": "~1.11.0",
1616
"morgan": "~1.9.0",
17-
"serve-favicon": "~2.4.5"
17+
"serve-favicon": "~2.4.5",
18+
"command-exists": "latest"
1819
},
1920
"nodemonConfig": {
2021
"ignore": [

public/js/app/webgit-home/webgit-home.component.js

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
(function() {
1+
(function(window, angular, $, localStorage) {
22
var webgitHomeModule = angular.module('WebgitHomeModule', ['ngRoute']);
33

44
webgitHomeModule.component('webgitHome', {
55
templateUrl: '/js/app/webgit-home/webgit-home.html',
66
controllerAs: 'vm',
7-
controller: ['WebgitHomeService', '$location', 'UtilsService', function WebgitHomeController(WebgitHomeService, $location, utils) {
8-
console.log('inside webgit home controller');
9-
7+
controller: ['WebgitHomeService', '$location', 'UtilsService', '$timeout', function WebgitHomeController(WebgitHomeService, $location, utils, $timeout) {
108
var vm = this;
119
var $cloneModal = $('#clone-modal');
1210

1311
var $responseModal = $('#response-modal');
1412
var $responseModalTitle = $responseModal.find('#response-title');
1513
var $responseModalBody = $responseModal.find('#response-body');
14+
var $settingsModal = $('#settings-modal');
1615

1716
$responseModal.on('hide.bs.modal', function(e) {
1817
$responseModalBody.html('');
@@ -26,14 +25,66 @@
2625
vm.openAfterCheckingOut = true;
2726
vm.testGit = testGit;
2827
vm.getRepoTitle = getRepoTitle;
28+
vm.viewSettingsModal = viewSettingsModal;
29+
30+
vm.saveGitExecutablePath = saveGitExecutablePath;
2931

3032
WebgitHomeService.getClonedRepos().then(function(data) {
3133
var allRepos = data.allRepos;
3234
vm.clonedRepos = allRepos;
3335
});
3436

37+
resetSettings();
38+
bindEvents();
39+
3540
return;
3641

42+
function resetSettings() {
43+
vm.settings = {
44+
gitExists: {}
45+
};
46+
}
47+
48+
function saveGitExecutablePath() {
49+
// save vm.settings.gitExists to local storage. rescan for settings.
50+
localStorage.setItem('gitonbrowser.gitPath', vm.settings.gitExists.path);
51+
validateSettings();
52+
}
53+
54+
function bindEvents() {
55+
$('.settings-obj').on('click', '.fix-this-error', function(e) {
56+
var $settingsObj = $(e.delegateTarget);
57+
$settingsObj.find('.settings-obj-fix').toggleClass('hidden');
58+
});
59+
}
60+
61+
function viewSettingsModal() {
62+
$settingsModal.modal('show');
63+
return validateSettings();
64+
}
65+
66+
function validateSettings() {
67+
resetSettings();
68+
var options = {};
69+
var gitExecutablePath = localStorage.getItem('gitonbrowser.gitPath');
70+
if(gitExecutablePath) {
71+
options.gitExecutablePath = gitExecutablePath;
72+
}
73+
return WebgitHomeService.getSettings(options).then(function(d) {
74+
if(d.errorCode) {
75+
switch(d.errorCode) {
76+
case 1: {
77+
// git not found.
78+
vm.settings.gitExists.err = 1;
79+
vm.settings.gitExists.msg = d.msg;
80+
vm.settings.gitExists.description = d.description;
81+
break;
82+
}
83+
}
84+
}
85+
});
86+
}
87+
3788
function getRepoTitle(path) {
3889
return utils.decodePath(path);
3990
}
@@ -54,8 +105,8 @@
54105
// close both modals
55106
$responseModal.one('hide.bs.modal', function() {
56107
$cloneModal.one('hide.bs.modal', function() {
57-
// if we redirect without settimeout, the overlay does not get dismissed.
58-
window.setTimeout(function() {
108+
// if we redirect without $timeout, the overlay does not get dismissed.
109+
$timeout(function() {
59110
WebgitHomeService.browseRepo(utils.decodePath(data.extraInfo.repoPath));
60111
}, 500);
61112
});
@@ -79,9 +130,16 @@
79130
this.browseRepo = browseRepo;
80131
this.clone = clone;
81132
this.testGit = testGit;
133+
this.getSettings = getSettings;
82134

83135
return;
84136

137+
function getSettings(options) {
138+
return $http.post('/settings', options).then(function(res) {
139+
return res.data;
140+
});
141+
}
142+
85143
function clone(pathOfRepo, pathOfDestination, subdirName) {
86144
return $http.post('/clonerepo', {
87145
url: window.encodeURIComponent(pathOfRepo),
@@ -110,4 +168,4 @@
110168
});
111169
}
112170
}]);
113-
})();
171+
})(window, window.angular, window.jQuery, window.localStorage);

public/js/app/webgit-home/webgit-home.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,30 @@
88

99
.home-card {
1010
margin-top: 30px;
11+
}
12+
13+
.home-settings-icon {
14+
cursor: pointer;
15+
color: #007bff;
16+
}
17+
18+
.home-settings-icon:hover {
19+
color: #6c757d;
20+
}
21+
22+
.home-settings-icon.has-error {
23+
color: #dc3545;
24+
}
25+
26+
.settings-obj .fix-this-error {
27+
display: none;
28+
cursor: pointer;
29+
}
30+
31+
.settings-obj .failed-setting .fix-this-error {
32+
display: block;
33+
}
34+
35+
.settings-obj-fix.hidden {
36+
display: none;
1137
}

public/js/app/webgit-home/webgit-home.html

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
<link href="/js/app/webgit-home/webgit-home.css" rel="stylesheet" />
33
<div class="row">
44
<div class="col-12">
5-
<h1 class="main-title">gitonbrowser</h1>
5+
<h1 class="main-title">gitonbrowser <span ng-click="vm.viewSettingsModal()" class="fa fa-gear home-settings-icon"></span></h1>
66
</div>
7+
</div>
8+
<div class="row">
9+
710
</div>
811
<div class="row">
912
<div class="col-sm-12 col-xs-12 col-md-6 col-lg-6 col-xl-4 home-card">
@@ -47,6 +50,36 @@ <h4 class="card-header">Browse cloned repository</h4>
4750
</div>
4851
</div>
4952
</div>
53+
<div class="modal fade" id="settings-modal" tabindex="-1" role="dialog">
54+
<div class="modal-dialog modal-lg" role="document">
55+
<div class="modal-content">
56+
<div class="modal-header">
57+
<h5 class="modal-title">Settings</h5>
58+
<button class="close" type="button" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
59+
</div>
60+
<div class="modal-body">
61+
<div class="container-fluid">
62+
<div class="row">
63+
<div class="col-12">
64+
<div class="settings-obj">
65+
<div class="alert" ng-class="vm.settings.gitExists.err ? 'failed-setting alert-danger' : 'alert-success'">{{vm.settings.gitExists.err ? vm.settings.gitExists.msg : 'Yay! I found GIT.'}}<span class="fix-this-error pull-right btn-link">Fix</span></div>
66+
<div class="settings-obj-fix hidden" ng-if="vm.settings.gitExists.err">
67+
<form class="form-inline">
68+
<div class="form-group mx-sm-3 mb-2">
69+
<label for="git-exec-path" class="">Path to GIT executible:&nbsp;</label>
70+
<input type="text" class="form-control" ng-model="vm.settings.gitExists.path" id="git-exec-path" placeholder="/usr/local/bin OR C:/Program Files/Git">
71+
</div>
72+
<button ng-click="vm.saveGitExecutablePath()" class="btn btn-primary mb-2">Save and Recheck</button>
73+
</form>
74+
</div>
75+
</div>
76+
</div>
77+
</div>
78+
</div>
79+
</div>
80+
</div>
81+
</div>
82+
</div>
5083
<div class="modal fade" id="clone-modal" tabindex="-1" role="dialog">
5184
<div class="modal-dialog modal-lg" role="document">
5285
<div class="modal-content">

routes/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ router.post('/testgit', function(req, res, next) {
3131
git.testGit({req, res});
3232
});
3333

34+
router.post('/settings', function(req, res, next) {
35+
// version of git running
36+
// git is in PATH?
37+
// path to installed git
38+
// username is configured for GIT
39+
// email is configured for GIT
40+
41+
git.getSettings({req, res});
42+
});
43+
3444
router.get('/browserepo', function(req, res) {
3545
let path = req.query.path,
3646
encodedPath = utils.encodePath(path);

0 commit comments

Comments
 (0)