Browse Source

Git repository handling

NGPixel 8 years ago
parent
commit
ca1882a9c3
6 changed files with 217 additions and 6 deletions
  1. 4 1
      .gitignore
  2. 23 0
      config.sample.yml
  3. 13 1
      controllers/pages.js
  4. 170 0
      models/git.js
  5. 5 4
      server.js
  6. 2 0
      views/pages/view.pug

+ 4 - 1
.gitignore

@@ -43,4 +43,7 @@ jspm_packages
 *.sublime-workspace
 
 # Config Files
-config.yml
+config.yml
+
+# App Repo
+repo

+ 23 - 0
config.sample.yml

@@ -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
 # -------------------------------------------------

+ 13 - 1
controllers/pages.js

@@ -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 - 0
models/git.js

@@ -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;
+
+	}
+
+};

+ 5 - 4
server.js

@@ -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]');
 });

+ 2 - 0
views/pages/view.pug

@@ -49,4 +49,6 @@ block content
 						| Primary bold title
 					h2.subtitle
 						| Primary bold subtitle
+					.content
+						!= contents