Git repository handling
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -44,3 +44,6 @@ jspm_packages | |||||||
|  |  | ||||||
| # Config Files | # Config Files | ||||||
| config.yml | config.yml | ||||||
|  |  | ||||||
|  | # App Repo | ||||||
|  | repo | ||||||
| @@ -38,6 +38,29 @@ redis: | |||||||
|   port: 6379 |   port: 6379 | ||||||
|   db: 0 |   db: 0 | ||||||
|  |  | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Git Connection Info | ||||||
|  | # ------------------------------------------------- | ||||||
|  | # Full explanation + examples in the documentation (https://requarks-wiki.readme.io/) | ||||||
|  |  | ||||||
|  | git: | ||||||
|  |   path: auto | ||||||
|  |   mode: remote | ||||||
|  |   url: https://github.com/Organization/Repo | ||||||
|  |   auth: | ||||||
|  |     type: ssh | ||||||
|  |     user: gitusername | ||||||
|  |     publickey: /etc/requarkswiki/keys/git.pub | ||||||
|  |     privatekey: /etc/requarkswiki/keys/git.key | ||||||
|  |     passphrase: SomeSshPassphrase | ||||||
|  |   # auth: | ||||||
|  |   #   type: oauth | ||||||
|  |   #   token: 1234567890abcdefghijklmnopqrstuvxyz | ||||||
|  |   # auth: | ||||||
|  |   #   type: basic | ||||||
|  |   #   user: johnsmith | ||||||
|  |   #   pass: password123 | ||||||
|  |  | ||||||
| # ------------------------------------------------- | # ------------------------------------------------- | ||||||
| # Secret key to use when encrypting sessions | # Secret key to use when encrypting sessions | ||||||
| # ------------------------------------------------- | # ------------------------------------------------- | ||||||
|   | |||||||
| @@ -7,7 +7,19 @@ var router = express.Router(); | |||||||
|  * Home |  * Home | ||||||
|  */ |  */ | ||||||
| router.get('/', (req, res) => { | router.get('/', (req, res) => { | ||||||
| 	res.render('pages/view'); |  | ||||||
|  | 	var md = require('markdown-it')({ | ||||||
|  | 		breaks: true, | ||||||
|  | 	  linkify: true, | ||||||
|  | 	  typographer: true | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	var Promise = require('bluebird'); | ||||||
|  | 	var fs = Promise.promisifyAll(require("fs")); | ||||||
|  | 	fs.readFileAsync("repo/Gollum.md", "utf8").then(function(contents) { | ||||||
|  |     res.render('pages/view', { contents: md.render(contents) }); | ||||||
|  |  	}); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| module.exports = router; | module.exports = router; | ||||||
							
								
								
									
										170
									
								
								models/git.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								models/git.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | |||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | var NodeGit = require("nodegit"), | ||||||
|  | 	Promise = require('bluebird'), | ||||||
|  | 	path = require('path'), | ||||||
|  | 	os = require('os'), | ||||||
|  | 	fs = Promise.promisifyAll(require("fs")), | ||||||
|  | 	_ = require('lodash'); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Git Model | ||||||
|  |  */ | ||||||
|  | module.exports = { | ||||||
|  |  | ||||||
|  | 	_git: null, | ||||||
|  | 	_repo: { | ||||||
|  | 		path: '', | ||||||
|  | 		exists: false, | ||||||
|  | 		inst: null | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Initialize Git model | ||||||
|  | 	 * | ||||||
|  | 	 * @param      {Object}  appconfig  The application config | ||||||
|  | 	 * @return     {Object}  Git model instance | ||||||
|  | 	 */ | ||||||
|  | 	init(appconfig) { | ||||||
|  |  | ||||||
|  | 		let self = this; | ||||||
|  |  | ||||||
|  | 		//-> Build repository path | ||||||
|  | 		 | ||||||
|  | 		if(_.isEmpty(appconfig.git.path) || appconfig.git.path === 'auto') { | ||||||
|  | 			self._repo.path = path.join(ROOTPATH, 'repo'); | ||||||
|  | 		} else { | ||||||
|  | 			self._repo.path = appconfig.git.path; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		//-> Initialize repository | ||||||
|  |  | ||||||
|  | 		self._initRepo(appconfig).then((repo) => { | ||||||
|  | 			self._repo.inst = repo; | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		return self; | ||||||
|  |  | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Initialize Git repository | ||||||
|  | 	 * | ||||||
|  | 	 * @param      {Object}  appconfig  The application config | ||||||
|  | 	 * @return     {Object}  Promise | ||||||
|  | 	 */ | ||||||
|  | 	_initRepo(appconfig) { | ||||||
|  |  | ||||||
|  | 		let self = this; | ||||||
|  |  | ||||||
|  | 		winston.info('[GIT] Initializing Git repository...'); | ||||||
|  |  | ||||||
|  | 		//-> Check if path is accessible | ||||||
|  |  | ||||||
|  | 		return fs.mkdirAsync(self._repo.path).catch((err) => { | ||||||
|  | 			if(err.code !== 'EEXIST') { | ||||||
|  | 				winston.error('Invalid Git repository path or missing permissions.'); | ||||||
|  | 			} | ||||||
|  | 		}).then(() => { | ||||||
|  |  | ||||||
|  | 			//-> Check if path already contains a git working folder | ||||||
|  |  | ||||||
|  | 			return fs.statAsync(path.join(self._repo.path, '.git')).then((stat) => { | ||||||
|  | 				self._repo.exists = stat.isDirectory(); | ||||||
|  | 			}).catch((err) => { | ||||||
|  | 				self._repo.exists = false; | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 		}).then(() => { | ||||||
|  |  | ||||||
|  | 			//-> Init repository | ||||||
|  |  | ||||||
|  | 			let repoInitOperation = null; | ||||||
|  |  | ||||||
|  | 			if(self._repo.exists) { | ||||||
|  |  | ||||||
|  | 				winston.info('[GIT] Using existing repository...'); | ||||||
|  | 				repoInitOperation = NodeGit.Repository.open(self._repo.path); | ||||||
|  |  | ||||||
|  | 			} else if(appconfig.git.remote) { | ||||||
|  |  | ||||||
|  | 				winston.info('[GIT] Cloning remote repository for first time...'); | ||||||
|  | 				let cloneOptions = self._generateCloneOptions(appconfig); | ||||||
|  | 				repoInitOperation = NodeGit.Clone(appconfig.git.url, self._repo.path, cloneOptions); | ||||||
|  |  | ||||||
|  | 			} else { | ||||||
|  |  | ||||||
|  | 				winston.info('[GIT] Using offline local repository...'); | ||||||
|  | 				repoInitOperation = NodeGit.Repository.init(self._repo.path, 0); | ||||||
|  |  | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return repoInitOperation; | ||||||
|  |  | ||||||
|  | 		}).catch((err) => { | ||||||
|  | 			winston.error('Unable to open or clone Git repository!'); | ||||||
|  | 			winston.error(err); | ||||||
|  | 		}).then((repo) => { | ||||||
|  |  | ||||||
|  | 			self._repo.inst = repo; | ||||||
|  |  | ||||||
|  | 			winston.info('[GIT] Git repository is now ready.'); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Generate Clone Options object | ||||||
|  | 	 * | ||||||
|  | 	 * @param      {Object}  appconfig  The application configuration | ||||||
|  | 	 * @return     {Object}  CloneOptions object | ||||||
|  | 	 */ | ||||||
|  | 	_generateCloneOptions(appconfig) { | ||||||
|  |  | ||||||
|  | 		let cloneOptions = {}; | ||||||
|  |  | ||||||
|  | 		cloneOptions.fetchOpts = { | ||||||
|  | 			callbacks: { | ||||||
|  | 				credentials: () => { | ||||||
|  |  | ||||||
|  | 					let cred = null; | ||||||
|  | 					switch(appconfig.git.auth.type) { | ||||||
|  | 						case 'basic': | ||||||
|  | 							cred = NodeGit.Cred.userpassPlaintextNew( | ||||||
|  | 								appconfig.git.auth.user, | ||||||
|  | 								appconfig.git.auth.pass | ||||||
|  | 							); | ||||||
|  | 						break; | ||||||
|  | 						case 'oauth': | ||||||
|  | 							cred = NodeGit.Cred.userpassPlaintextNew( | ||||||
|  | 								appconfig.git.auth.token, | ||||||
|  | 								"x-oauth-basic" | ||||||
|  | 							); | ||||||
|  | 						break; | ||||||
|  | 						case 'ssh': | ||||||
|  | 							cred = NodeGit.Cred.sshKeyNew( | ||||||
|  | 								appconfig.git.auth.user, | ||||||
|  | 								appconfig.git.auth.publickey, | ||||||
|  | 								appconfig.git.auth.privatekey, | ||||||
|  | 								appconfig.git.auth.passphrase | ||||||
|  | 							); | ||||||
|  | 						break; | ||||||
|  | 						default: | ||||||
|  | 							cred = NodeGit.Cred.defaultNew(); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					return cred; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 		if(os.type() === 'Darwin') { | ||||||
|  | 			cloneOptions.fetchOpts.callbacks.certificateCheck = () => { return 1; }; // Bug in OS X, bypass certs check workaround | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return cloneOptions; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
| @@ -9,13 +9,14 @@ | |||||||
| // ---------------------------------------- | // ---------------------------------------- | ||||||
|  |  | ||||||
| global.winston = require('winston'); | global.winston = require('winston'); | ||||||
| winston.info('Requarks Wiki is initializing...'); | winston.info('[SERVER] Requarks Wiki is initializing...'); | ||||||
|  |  | ||||||
| global.ROOTPATH = __dirname; | global.ROOTPATH = __dirname; | ||||||
|  |  | ||||||
| var appconfig = require('./models/config')('./config.yml'); | var appconfig = require('./models/config')('./config.yml'); | ||||||
| global.db = require('./models/mongodb')(appconfig); | global.db = require('./models/mongodb')(appconfig); | ||||||
| global.red = require('./models/redis')(appconfig); | global.red = require('./models/redis')(appconfig); | ||||||
|  | global.git = require('./models/git').init(appconfig); | ||||||
|  |  | ||||||
| var _ = require('lodash'); | var _ = require('lodash'); | ||||||
| var express = require('express'); | var express = require('express'); | ||||||
| @@ -155,9 +156,9 @@ app.use(function(err, req, res, next) { | |||||||
| // Start HTTP server | // Start HTTP server | ||||||
| // ---------------------------------------- | // ---------------------------------------- | ||||||
|  |  | ||||||
| winston.info('Requarks Wiki has initialized successfully.'); | winston.info('[SERVER] Requarks Wiki has initialized successfully.'); | ||||||
|  |  | ||||||
| winston.info('Starting HTTP server on port ' + appconfig.port + '...'); | winston.info('[SERVER] Starting HTTP server on port ' + appconfig.port + '...'); | ||||||
|  |  | ||||||
| app.set('port', appconfig.port); | app.set('port', appconfig.port); | ||||||
| var server = http.createServer(app); | var server = http.createServer(app); | ||||||
| @@ -183,5 +184,5 @@ server.on('error', (error) => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| server.on('listening', () => { | server.on('listening', () => { | ||||||
|   winston.info('HTTP server started successfully! [RUNNING]'); |   winston.info('[SERVER] HTTP server started successfully! [RUNNING]'); | ||||||
| }); | }); | ||||||
| @@ -49,4 +49,6 @@ block content | |||||||
| 						| Primary bold title | 						| Primary bold title | ||||||
| 					h2.subtitle | 					h2.subtitle | ||||||
| 						| Primary bold subtitle | 						| Primary bold subtitle | ||||||
|  | 					.content | ||||||
|  | 						!= contents | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user