Permalink
Browse files

inital commit. should work :)

  • Loading branch information...
jaredly committed Sep 11, 2013
0 parents commit ed30725710469e3cd6843d7a6915eec6aaa30438
Showing with 274 additions and 0 deletions.
  1. +14 −0 Readme.md
  2. +43 −0 config.html
  3. +34 −0 package.json
  4. +29 −0 static/project_config.js
  5. +35 −0 webapp.js
  6. +119 −0 worker.js
@@ -0,0 +1,14 @@
+## Git provider
+
+Allow strider to use any git repository for a project.
+
+### Config
+
+- url
+- display_url (optional)
+- auth
+ - ssh
+ - custom priv/pubkey if you want
+ - https
+ - username
+ - password
@@ -0,0 +1,43 @@
+<label>
+ <span>Url</span>
+ <input type="text" ng-model="config.url" placeholder="example.com/my/repo.git">
+</label>
+<span class="help-text">Don't include "git@" or "https://".</span>
+<label>
+ <span>Display Url</span>
+ <input type="text" ng-model="config.display_url" placeholder="http://example.com/my/repo">
+</label>
+<span class="help-block">
+ The url to browse the repository (optional). If provided, the
+ there will be a <i class="icon-code-fork"></i> link next to the
+ project name.
+</span>
+<div class="auth-type">
+ <label>Auth type</label>
+ <label class="checkbox">
+ <input name="authtype" ng-model="config.auth.type" type="radio" value="ssh"> ssh
+ </label>
+ <label class="checkbox">
+ <input name="authtype" ng-model="config.auth.type" type="radio" value="https"> https
+ </label>
+</div>
+<div ng-show="config.auth.type === 'ssh'">
+ <span class="help-text">
+ Leave these blank to use the project's private and public keys
+ (you can find those under the "General" tab).
+ </span>
+ <label>Private Key</label>
+ <textarea ng-model="config.auth.privkey"></textarea>
+ <label>Public Key</label>
+ <textarea ng-model="config.auth.pubkey"></textarea>
+</div>
+<div ng-show="config.auth.type === 'https'">
+ <span class="help-text">Https auth</span>
+ <label>
+ <input type="text" ng-model="config.auth.username" placeholder="Username">
+ </label>
+ <label>
+ <input type="password" ng-model="config.auth.password" placeholder="Password">
+ </label>
+</div>
+<button ng-click="save()" ng-disabled="saving">Save</button>
@@ -0,0 +1,34 @@
+{
+ "name": "strider-git",
+ "version": "0.0.0",
+ "description": "Strider provider for git repositories",
+ "main": "worker.js",
+ "scripts": {
+ "test": "make test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Strider-CD/strider-git"
+ },
+ "keywords": [
+ "strider",
+ "plugin",
+ "provider",
+ "git"
+ ],
+ "author": "Jared Forsyth <jared@jaredforsyth.com>",
+ "license": "MIT",
+ "readmeFilename": "Readme.md",
+ "strider": {
+ "id": "git",
+ "title": "Git",
+ "type": "provider",
+ "webapp": "webapp.js",
+ "worker": "worker.js",
+ "inline_icon": "code-fork",
+ "panel": {
+ "src": "templates/project-config.html",
+ "controller": "GitController"
+ }
+ }
+}
@@ -0,0 +1,29 @@
+
+app.controller('GitController', ['$scope', function ($scope) {
+ $scope.saving = false;
+ $scope.save = function () {
+ $scope.saving = true;
+ $.ajax({
+ url: 'api/git/config',
+ type: 'PUT',
+ data: $scope.config,
+ dataType: 'json',
+ success: function(data, ts, xhr) {
+ $scope.success(data.message);
+ $scope.saving = false;
+ $scope.config = data.config;
+ $scope.$root.$digest();
+ },
+ error: function(xhr, ts, e) {
+ $scope.saving = false;
+ if (xhr && xhr.responseText) {
+ var data = $.parseJSON(xhr.responseText);
+ $scope.error("Error saving config: " + data.errors[0]);
+ } else {
+ $scope.error("Error saving config: " + e);
+ }
+ $scope.$root.$digest();
+ }
+ });
+ };
+}]);
@@ -0,0 +1,35 @@
+
+function sanitizeConfig(config) {
+ if (!config.auth) return false
+ return {
+ url: config.url,
+ display_url: config.display_url,
+ auth: {
+ type: config.auth.type === 'ssh' ? 'ssh' : 'https',
+ privkey: config.auth.privkey,
+ pubkey: config.auth.pubkey,
+ username: config.auth.username,
+ password: config.auth.password
+ }
+ }
+}
+
+module.exports = {
+ routes: function (app, context) {
+ app.get('config', context.auth.projectAdmin, function (req, res) {
+ res.send(req.providerConfig())
+ })
+ app.put('config', context.auth.projectAdmin, function (req, res) {
+ // validate the config
+ var config = sanitizeConfig(req.body)
+ req.providerConfig(config, function (err) {
+ if (err) {
+ res.status(500)
+ return res.send({errors: [err.message]})
+ }
+ res.send({success: true, message: 'Saved git config!', config: config})
+ })
+ })
+ }
+}
+
119 worker.js
@@ -0,0 +1,119 @@
+
+var gitane = require('gitane')
+ , shellescape = require('shell-escape')
+
+ , path = require('path')
+ , fs = require('fs')
+
+function shellEscape(one) {
+ return shellescape([one])
+}
+
+function httpsCmd(config, branch) {
+ var url = 'https://' + config.auth.username + ':' + config.auth.password + '@' + config.url
+ , screen = 'git clone --recursive ' + 'https://[username]:[password]@' + config.url + ' .'
+ , args = ['clone', '--recursive', url, '.']
+ if (branch) {
+ args = args.concat(['-b', branch])
+ screen += ' -b ' + branch
+ }
+ return {
+ command: 'git',
+ args: args
+ screen: screen
+ }
+}
+
+// run a strider command with gitane
+function gitaneCmd(cmd, dest, privkey, context, done) {
+ var start = new Date()
+ context.status('command.start', { text: cmd, time: start, plugin: context.plugin })
+ gitane.run({
+ emitter: {
+ emit: context.status
+ },
+ cmd: cmd,
+ baseDir: dest,
+ privKey: privkey,
+ detached: true
+ }, function (err, stdout, stderr, exitCode) {
+ var end = new Date()
+ , elapsed = end.getTime() - start.getTime()
+ if (err) {
+ context.log('Gitane error:', err.message)
+ }
+ context.log('gitane command done %s; exit code %s; duration %s', cmd, exitCode, elapsed)
+ context.status('command.done', {exitCode: exitCode, time: end, elapsed: elapsed})
+ done(err ? 500 : exitCode)
+ })
+}
+
+function gitCmd(cmd, dest, config, job, context, done) {
+ if (config.auth.type === 'ssh') {
+ return gitaneCmd(cmd, dest, config.auth.privkey || job.project.privkey, context, done)
+ }
+ context.cmd({
+ cmd: cmd,
+ cwd: dest
+ }, done)
+}
+
+function pull(dest, config, job, context, done) {
+ context.cmd({
+ cmd: 'git reset --hard',
+ cwd: dest
+ }, function (exitCode) {
+ gitCmd('git pull', dest, config, job, context, done)
+ })
+}
+
+function clone(dest, config, job, context, done) {
+ if (config.auth.type === 'ssh') {
+ var cmd = 'git clone --recursive ' + shellEscape('git@' + config.url.replace('/', ':')) + ' .'
+ if (job.ref.branch) {
+ cmd += ' -b ' + job.ref.branch
+ }
+ return gitaneCmd(cmd, dest, config.auth.privkey || job.project.privkey, context, done)
+ }
+ context.cmd({
+ cmd: httpsCmd(config),
+ cwd: dest
+ }, done)
+}
+
+function badCode(name, code) {
+ var e = new Error(name + ' failed with code ' + code)
+ e.code = code
+ e.exitCode = code
+ return e
+}
+
+module.exports = {
+ fetch: function (dest, userConfig, config, job, context, done) {
+ fs.exists(path.join(dest, '.git'), function (err, exists) {
+ // if .git exists, pull, otherwise clone
+ (exists ? pull : clone)(dest, config, job, context, function (exitCode) {
+ if (exitCode) return done(badCode('Command', exitCode))
+ // fetch the ref
+ if (job.ref.branch) {
+ return context.cmd({
+ cmd: 'git checkout -qf ' + shellEscape(job.ref.id),
+ cwd: dest
+ }, function (exitCode) {
+ done(exitCode && badCode('Checkout', exitCode))
+ })
+ }
+ gitCmd('git fetch origin ' + shellEscape(job.ref.fetch), dest, config, job, context, function (exitCode) {
+ if (exitCode) return done(badCode('Fetch ' + job.ref.fetch, exitCode))
+ context.cmd({
+ cmd: 'git checkout -qf FETCH_HEAD',
+ cwd: dest
+ }, function (exitCode) {
+ done(exitCode && badCode('Checkout', exitCode))
+ })
+ })
+ })
+ })
+ }
+}
+

0 comments on commit ed30725

Please sign in to comment.