Git repository handling
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -44,3 +44,6 @@ jspm_packages
 | 
			
		||||
 | 
			
		||||
# Config Files
 | 
			
		||||
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