Git repository handling
This commit is contained in:
		
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -43,4 +43,7 @@ jspm_packages | ||||
| *.sublime-workspace | ||||
|  | ||||
| # Config Files | ||||
| config.yml | ||||
| config.yml | ||||
|  | ||||
| # App Repo | ||||
| repo | ||||
| @@ -38,6 +38,29 @@ redis: | ||||
|   port: 6379 | ||||
|   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 | ||||
| # ------------------------------------------------- | ||||
|   | ||||
| @@ -7,7 +7,19 @@ var router = express.Router(); | ||||
|  * Home | ||||
|  */ | ||||
| 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; | ||||
							
								
								
									
										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'); | ||||
| winston.info('Requarks Wiki is initializing...'); | ||||
| winston.info('[SERVER] Requarks Wiki is initializing...'); | ||||
|  | ||||
| global.ROOTPATH = __dirname; | ||||
|  | ||||
| var appconfig = require('./models/config')('./config.yml'); | ||||
| global.db = require('./models/mongodb')(appconfig); | ||||
| global.red = require('./models/redis')(appconfig); | ||||
| global.git = require('./models/git').init(appconfig); | ||||
|  | ||||
| var _ = require('lodash'); | ||||
| var express = require('express'); | ||||
| @@ -155,9 +156,9 @@ app.use(function(err, req, res, next) { | ||||
| // 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); | ||||
| var server = http.createServer(app); | ||||
| @@ -183,5 +184,5 @@ server.on('error', (error) => { | ||||
| }); | ||||
|  | ||||
| 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 | ||||
| 					h2.subtitle | ||||
| 						| Primary bold subtitle | ||||
| 					.content | ||||
| 						!= contents | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user