gitty 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ class Gitty::Hook::Manager < Gitty::Runner
2
+ include ::Gitty::Helpers
3
+ def initialize(args, stdout = STDOUT, stderr = STDERR)
4
+ super
5
+ @hookname = args.shift
6
+ end
7
+
8
+ def options
9
+ @options ||= super.update(:kind => :local)
10
+ end
11
+
12
+ def src_hook_file
13
+ Gitty.find_asset("hooks/#{@hookname}")
14
+ end
15
+
16
+ def master_hook_file
17
+ @master_hook_file ||= hooks_directory + @hookname
18
+ end
19
+
20
+ def meta_data
21
+ @meta_data ||= Gitty.extract_meta_data(File.read(src_hook_file))
22
+ end
23
+
24
+ def run
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def target_file(hook)
29
+ @target_file ||= file_with_existing_directory!(base_directory + "#{hook}.d/#{@hookname}")
30
+ end
31
+
32
+ def base_directory
33
+ @base_directory ||= existing_directory!(".git/hooks/#{options[:kind]}")
34
+ end
35
+
36
+ def helpers_directory
37
+ @helpers_directory ||= existing_directory!(".git/hooks/#{options[:kind]}/helpers")
38
+ end
39
+
40
+ def hooks_directory
41
+ existing_directory!(base_directory + "hooks")
42
+ end
43
+
44
+ def option_parser
45
+ @option_parser ||= super.tap do |opts|
46
+ opts.on("-l", "--local", "Local hook (default)") { |l| options[:kind] = :local }
47
+ opts.on("-s", "--shared", "Remote hook") { |l| options[:kind] = :shared }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,34 @@
1
+ class Gitty::Hook::Publish < Gitty::Runner
2
+ include ::Gitty::Helpers
3
+
4
+ def run
5
+ rev = nil
6
+ puts "Publishing with message #{options[:message].inspect}"
7
+ with_env_var("GIT_OBJECT_DIRECTORY", File.join(Dir.pwd, ".git/objects")) do
8
+ Dir.chdir(".git/hooks/shared") do
9
+ cmd(*%w[git add . -A])
10
+ cmd(*%w[git commit -m].push(options[:message]))
11
+ rev = %x{git rev-parse HEAD}.chomp
12
+ end
13
+ end
14
+ # back on the mother repo...
15
+ cmd(*%w[git push origin -f].push("#{rev}:refs/heads/--hooks--"))
16
+ end
17
+
18
+ protected
19
+ def option_parser
20
+ @option_parser ||= super.tap do |opts|
21
+ opts.banner = "Usage: git hook publish [options]"
22
+ opts.on("-m [message]", "--message [message]", "Message for commit (required)") do |m|
23
+ options[:message] = m
24
+ end
25
+ end
26
+ end
27
+
28
+ def parse_args!
29
+ super
30
+ if options[:message].nil?
31
+ puts option_parser
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ require GITTY_PATH + "commands/manager"
2
+ class Gitty::Hook::Remove < Gitty::Hook::Manager
3
+ include FileUtils
4
+ def run
5
+ rm(master_hook_file)
6
+ meta_data["targets"].each do |target|
7
+ rm(target_file(target))
8
+ end
9
+ # TODO - cleanup helpers
10
+ end
11
+
12
+ def option_parser
13
+ @option_parser ||= super.tap do |opts|
14
+ opts.banner = "Usage: git hook remove [opts] hook-name"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ require 'fileutils'
2
+ class Gitty::Hook::Shell < Gitty::Runner
3
+ include ::Gitty::Helpers
4
+
5
+ def run
6
+ exec "bash --init-file #{create_init_file}"
7
+ end
8
+
9
+ def create_init_file
10
+ "/tmp/gitty-shell-init".tap do |filename|
11
+ File.open(filename, "wb") do |f|
12
+ f.puts(<<-EOF)
13
+ pushd $HOME > /dev/null
14
+ [ -f $HOME/.bashrc ] && . $HOME/.bashrc
15
+ [ -f $HOME/.bash_profile ] && . $HOME/.bash_profile
16
+ popd > /dev/null
17
+ export GIT_OBJECT_DIRECTORY="$(pwd)/.git/objects"
18
+
19
+ export PS1="Shared Hooks [$(basename $(pwd))]$ "
20
+ cd .git/hooks/shared
21
+ rm "#{filename}"
22
+ EOF
23
+ end
24
+ end
25
+ end
26
+
27
+ def option_parser
28
+ super.tap do |opts|
29
+ opts.banner = "Usage: git hook shell"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ module Gitty::Helpers
2
+ def existing_directory!(dir)
3
+ FileUtils.mkdir_p(dir)
4
+ Pathname.new(dir)
5
+ end
6
+
7
+ def file_with_existing_directory!(path)
8
+ FileUtils.mkdir_p(File.dirname(path))
9
+ Pathname.new(path)
10
+ end
11
+
12
+ def with_env_var(name, value, &block)
13
+ previous_value, ENV[name] = ENV[name], value
14
+ yield
15
+ ENV[name] = previous_value
16
+ end
17
+
18
+ def cmd(*args)
19
+ system(*args.flatten)
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ class Gitty::Hook < Gitty::Runner
2
+ COMMANDS = %w[
3
+ init
4
+ list
5
+ add
6
+ remove
7
+ publish
8
+ shell
9
+ ]
10
+ COMMANDS.each do |cmd|
11
+ autoload cmd.classify.to_sym, (GITTY_PATH + "commands/#{cmd}.rb").to_s
12
+ end
13
+
14
+ def initialize(args, stdout = STDOUT, stderr = STDERR)
15
+ @args, @stdout, @stderr = args, stdout, stderr
16
+ if COMMANDS.include?(args.first)
17
+ @target = Gitty::Hook.const_get(args.shift.classify).new(args, stdout, stderr)
18
+ else
19
+ parse_args!
20
+ end
21
+ end
22
+
23
+ def option_parser
24
+ @option_parser ||= super.tap do |opts|
25
+ opts.banner = "Usage: git hook [command]\nCommands are: #{COMMANDS.join(', ')}"
26
+ end
27
+ end
28
+
29
+ def run
30
+ unless File.directory?(".git")
31
+ stderr.puts "You must run git hook from the root of a git repository"
32
+ exit 1
33
+ end
34
+ @target && @target.run
35
+ end
36
+
37
+ def parse_args!
38
+ opt_p = option_parser
39
+ opt_p.parse!(args)
40
+ puts opt_p
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ require "optparse"
2
+ class Gitty::Runner
3
+ attr_reader :stdout, :stderr, :args
4
+
5
+ def initialize(args, stdout = STDOUT, stderr = STDERR)
6
+ @args, @stdout, @stderr = args, stdout, stderr
7
+ parse_args!
8
+ end
9
+
10
+ def options
11
+ @options ||= {}
12
+ end
13
+
14
+ def run
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def option_parser
19
+ @option_parser ||= OptionParser.new do |opts|
20
+ opts.banner = "Usage: #{$0}"
21
+ opts.separator "Options:"
22
+ opts.on('--help', "Show help") do |h|
23
+ @show_help = opts
24
+ end
25
+ end
26
+ end
27
+
28
+ def handle_show_help
29
+ if @show_help
30
+ puts @show_help
31
+ exit(1)
32
+ end
33
+ end
34
+
35
+ def self.run(args, stdout = STDOUT, stderr = STDERR)
36
+ new(args, stdout, stderr).run
37
+ end
38
+
39
+ protected
40
+ def parse_args!
41
+ option_parser.parse!(args)
42
+ handle_show_help
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+ def constantize
3
+ Object.module_eval("::" + self)
4
+ end
5
+
6
+ def underscore
7
+ gsub(/(^|\b)[A-Z]/) { |l| l.downcase}.gsub(/[A-Z]/) { |l| "_#{l.downcase}" }.gsub("::", "/")
8
+ end
9
+
10
+ def classify
11
+ gsub(/^[a-z]/) { |l| l.upcase}.gsub(/_[a-z]/) { |l| l[1..1].upcase}.gsub(/\b[a-z]/) {|l| l.upcase}.gsub("/", "::")
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path('../../spec_helper', File.dirname(__FILE__))
2
+ require 'stringio'
3
+
4
+ describe Gitty::Hook::Add do
5
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Gitty do
4
+ describe ".asset_file" do
5
+ it "searches first in the specified $GITTY_ASSETS environment variable" do
6
+ ENV.stub!(:[]).with("GITTY_ASSETS").and_return("/tmp/assets")
7
+ File.stub!(:exist?).with("/tmp/assets/helpers/helpful").and_return(true)
8
+ File.stub!(:exist?).with(ASSETS_PATH + "helpers/helpful").and_return(true)
9
+
10
+ Gitty.find_asset("helpers/helpful").should == "/tmp/assets/helpers/helpful"
11
+ end
12
+
13
+ it "searches the core ASSETS_PATH if GITTY_ASSETS is not defined" do
14
+ ENV.stub!(:[]).with("GITTY_ASSETS").and_return(nil)
15
+ File.stub!(:exist?).with((ASSETS_PATH + "helpers/helpful").to_s).and_return(true)
16
+ Gitty.find_asset("helpers/helpful").should == (ASSETS_PATH + "helpers/helpful").to_s
17
+ end
18
+
19
+ it "returns nil if none the file is not found" do
20
+ Gitty.find_asset("willy/wonka").should be_nil
21
+ end
22
+ end
23
+
24
+ describe ".extract_meta_data" do
25
+ it "extracts meta data from a stream" do
26
+ stream = <<-EOF
27
+ #!/usr/bash
28
+
29
+ # description: hi
30
+ # targets: ["post-merge", "post-checkout"]
31
+ #
32
+
33
+ here's my hook
34
+ EOF
35
+ Gitty.extract_meta_data(stream).should == {
36
+ "description" => "hi",
37
+ "targets" => ["post-merge", "post-checkout"]
38
+ }
39
+ end
40
+
41
+ it "returns nil when no data found" do
42
+ stream = <<-EOF
43
+ #!/usr/bash
44
+ #
45
+ #
46
+ EOF
47
+ Gitty.extract_meta_data(stream).should == nil
48
+ end
49
+
50
+ it "returns the data when there's no actual content" do
51
+ stream = <<-EOF
52
+ #!/usr/bash
53
+ #
54
+ # description: hi
55
+ EOF
56
+ Gitty.extract_meta_data(stream).should == {"description" => "hi"}
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + "/../lib/gitty"
2
+ SPEC_PATH = GITTY_ROOT_PATH + "spec"
3
+ require 'rubygems'
4
+ require 'cucumber'
5
+ require SPEC_PATH + "support/constants.rb"
6
+ require "spec"
@@ -0,0 +1 @@
1
+ BIN_PATH = GITTY_LIB_PATH + "../bin"
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Harper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-21 00:00:00 -07:00
13
+ default_executable: git-hook
14
+ dependencies: []
15
+
16
+ description: Unobtrusively extend git
17
+ email: timcharper@gmail.com
18
+ executables:
19
+ - git-hook
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.textile
25
+ files:
26
+ - LICENSE
27
+ - README.textile
28
+ - Rakefile
29
+ - assets/helpers/git-cleanup-branches
30
+ - assets/helpers/git-strip-new-whitespace
31
+ - assets/helpers/git-submodule-helper
32
+ - assets/helpers/git-trash
33
+ - assets/helpers/git-when-introduced
34
+ - assets/helpers/hookd_wrapper
35
+ - assets/hooks/clean-patches
36
+ - assets/hooks/git-post-checkout-submodules
37
+ - assets/hooks/git-prevent-messy-rebase
38
+ - assets/hooks/prevent-nocommit-tags
39
+ - bin/git-hook
40
+ - cucumber.yml
41
+ - lib/ext.rb
42
+ - lib/gitty.rb
43
+ - lib/gitty/commands/add.rb
44
+ - lib/gitty/commands/init.rb
45
+ - lib/gitty/commands/list.rb
46
+ - lib/gitty/commands/manager.rb
47
+ - lib/gitty/commands/publish.rb
48
+ - lib/gitty/commands/remove.rb
49
+ - lib/gitty/commands/shell.rb
50
+ - lib/gitty/helpers.rb
51
+ - lib/gitty/hook.rb
52
+ - lib/gitty/runner.rb
53
+ - lib/string.rb
54
+ - spec/gitty/commands/add_spec.rb
55
+ - spec/gitty_spec.rb
56
+ - spec/spec_helper.rb
57
+ - spec/support/constants.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/timcharper/gitty
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.5
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Unobtrusively extend git
86
+ test_files:
87
+ - spec/gitty/commands/add_spec.rb
88
+ - spec/gitty_spec.rb
89
+ - spec/spec_helper.rb
90
+ - spec/support/constants.rb