gitty 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,6 +39,7 @@ module GitMethods
39
39
  end
40
40
  end
41
41
  include GitMethods
42
+ HELPERS = File.expand_path(ENV['HELPERS'], Dir.pwd)
42
43
 
43
44
  chdir_parent
44
45
  current_submodules = list_submodules('HEAD')
@@ -65,10 +66,35 @@ previous_submodules = list_submodules('HEAD@{1}')
65
66
  when rev != current_submodules[path]
66
67
  output_submodule_header(path)
67
68
  # it should be updated to the latest
68
- # Fetch if it the change doesn't exist
69
69
  Dir.chdir(path) do
70
+ # Fetch if it the change doesn't exist
70
71
  system("(git show '#{current_submodules[path]}' 2> /dev/null 1> /dev/null) || git fetch")
71
- system("git checkout '#{current_submodules[path]}'")
72
+
73
+ current_rev = current_submodules[path]
74
+ STDERR.puts("submodule is pointing to #{rev}")
75
+ rev, ref_kind, ref = %x{git for-each-ref}.split("\n").map { |l| l.split(" ") }.detect {|l| l.first == current_rev }
76
+
77
+ if ref.nil?
78
+ STDERR.puts "no known branch is currently at #{current_rev}, so we had to detach your HEAD."
79
+ STDERR.puts "here are some suggestions: "
80
+ system("git branch --contains #{current_rev} -a | egrep -v 'no branch|HEAD' 1>&2")
81
+ exit 1
82
+ end
83
+ if ref.match(/^refs\/heads/)
84
+ exec("git checkout '#{File.basename(ref)}'")
85
+ end
86
+
87
+ if ref.match(/^refs\/remotes/) then
88
+ local_ref=File.basename(ref)
89
+
90
+ STDERR.puts "Remote branch #{ref} matches"
91
+ divergent_commits=%x{git rev-list #{ref}..#{local_ref}}.strip
92
+ if divergent_commits.empty?
93
+ STDERR.puts "fastforwarding #{local_ref} to #{ref}"
94
+ system("git branch -f #{local_ref} #{ref}")
95
+ exec("git checkout #{local_ref}")
96
+ end
97
+ end
72
98
  end
73
99
  end
74
100
  end
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  $: << File.dirname(__FILE__) + "/../lib/"
3
3
  require "gitty"
4
- Gitty::Hook.new(ARGV).run
4
+ Gitty::HookCommand.new(ARGV).run
@@ -25,31 +25,8 @@ module Gitty
25
25
  end
26
26
  nil
27
27
  end
28
-
29
- def self.creating_dir_if_nonexistant(dir)
30
- FileUtils.mkdir_p(dir)
31
- Pathname.new(dir)
32
- end
33
-
34
- def self.extract_meta_data(string_or_io)
35
- io = string_or_io.respond_to?(:readline) ? string_or_io : StringIO.new(string_or_io)
36
- meta_yaml = ""
37
- begin
38
- while line = io.readline
39
- next unless line.match(/^# (description.+)/)
40
- meta_yaml = "#{$1}\n"
41
- break
42
- end
43
-
44
- while line = io.readline
45
- break unless line.match(/^# (.+)/)
46
- meta_yaml << "#{$1}\n"
47
- end
48
- rescue EOFError
49
- end
50
- meta_yaml.empty? ? nil : YAML.load(meta_yaml)
51
- end
52
28
  end
53
29
 
54
30
  require "gitty/runner.rb"
55
31
  require "gitty/hook.rb"
32
+ require "gitty/hook_command.rb"
@@ -1,5 +1,5 @@
1
1
  require 'fileutils'
2
- class Gitty::Hook::Init < Gitty::Runner
2
+ class Gitty::HookCommand::Init < Gitty::Runner
3
3
  include ::Gitty::Helpers
4
4
 
5
5
  CLIENT_HOOKS = %w[
@@ -34,7 +34,7 @@ class Gitty::Hook::Init < Gitty::Runner
34
34
  cmd(*%w[git symbolic-ref HEAD refs/heads/--hooks--])
35
35
  cmd(*%w[git commit --allow-empty -m initial\ commit])
36
36
  end
37
- cmd(*%w[git reset --hard], hooks_rev) if hooks_rev
37
+ cmd(*%w[git reset --hard] + hooks_rev) if hooks_rev
38
38
  end
39
39
  end
40
40
  end
@@ -0,0 +1,32 @@
1
+ class Gitty::HookCommand::Install < Gitty::Runner
2
+ include FileUtils
3
+ def initialize(args, stdout = STDOUT, stderr = STDERR)
4
+ super
5
+ @hookname = args.shift
6
+ end
7
+
8
+ def run
9
+ hook = Gitty::Hook.find(@hookname, :installed => false)
10
+ if hook.nil?
11
+ stderr.puts "no hook named '#{@hookname}' found."
12
+ exit 1
13
+ end
14
+
15
+ hook.install(options[:kind])
16
+ if options[:kind] == :shared
17
+ stdout.puts "To propagate this change other developers, run 'git hook publish -m \"added #{hook.name}...\""
18
+ end
19
+ end
20
+
21
+ def options
22
+ @options ||= super.update(:kind => :local)
23
+ end
24
+
25
+ def option_parser
26
+ @option_parser ||= super.tap do |opts|
27
+ opts.banner = "Usage: git hook install [opts] hook-name"
28
+ opts.on("-l", "--local", "Local hook (default)") { |l| options[:kind] = :local }
29
+ opts.on("-s", "--shared", "Remote hook") { |l| options[:kind] = :shared }
30
+ end
31
+ end
32
+ end
@@ -1,8 +1,8 @@
1
1
  require 'fileutils'
2
- class Gitty::Hook::List < Gitty::Runner
2
+ class Gitty::HookCommand::List < Gitty::Runner
3
3
  include ::Gitty::Helpers
4
4
  include FileUtils
5
- KINDS = [:local, :shared, :available]
5
+ KINDS = [:local, :shared, :uninstalled]
6
6
 
7
7
  def run
8
8
  stdout.puts "Listing hooks"
@@ -11,17 +11,19 @@ class Gitty::Hook::List < Gitty::Runner
11
11
  which_to_show.each { |w| show_hooks(w) }
12
12
  end
13
13
 
14
+ def all_hooks
15
+ @all_hooks = Gitty::Hook.find_all
16
+ end
17
+
14
18
  def show_hooks(which)
15
19
  case which
16
- when :local then show_local_or_shared_hooks('local')
17
- when :shared then show_local_or_shared_hooks('shared')
18
- when :available then show_available_hooks
20
+ when :local, :shared then show_local_or_shared_hooks(which)
21
+ when :uninstalled then show_uninstalled_hooks
19
22
  end
20
23
  end
21
24
 
22
25
  def show_local_or_shared_hooks(which)
23
- hook_names = filenames_in(installed_hooks_path(which))
24
- return if hook_names.empty?
26
+ hook_names = all_hooks.select { |h| h.install_kind == which.to_sym }.map(&:name)
25
27
  puts "#{which}:\n#{listify(hook_names)}\n\n"
26
28
  end
27
29
 
@@ -29,25 +31,11 @@ class Gitty::Hook::List < Gitty::Runner
29
31
  hooks.map { |h| "- #{h}" }.join("\n")
30
32
  end
31
33
 
32
- def filenames_in(dir)
33
- if File.directory?(dir)
34
- Dir.glob((dir + "*").to_s).sort.map do |path|
35
- File.basename(path)
36
- end
37
- else
38
- []
39
- end
40
- end
41
-
42
- def installed_hooks_path(which)
43
- Pathname.new(".git/hooks/#{which}/hooks")
44
- end
45
-
46
- def show_available_hooks
47
- all_hooks = Gitty.asset_paths.map {|asset_path| filenames_in(asset_path + "hooks")}.flatten
48
- installed_hooks = [:local, :shared].map { |which| filenames_in(installed_hooks_path(which)) }.flatten
49
- available_hooks = all_hooks.sort - installed_hooks.sort
50
- puts "available:\n#{listify(available_hooks)}\n\n"
34
+ def show_uninstalled_hooks
35
+ available_hook_names = all_hooks.select { |h| ! h.installed? }.map(&:name)
36
+ installed_hook_names = all_hooks.select { |h| h.installed? }.map(&:name)
37
+ uninstalled_hooks = (available_hook_names - installed_hook_names).sort
38
+ puts "uninstalled:\n#{listify(uninstalled_hooks)}\n\n"
51
39
  end
52
40
 
53
41
  def option_parser
@@ -56,11 +44,11 @@ class Gitty::Hook::List < Gitty::Runner
56
44
  opts.on("-l", "--local", "Show local hooks") do
57
45
  options[:local] = true
58
46
  end
59
- opts.on("-r", "--shared", "Show shared hooks") do
47
+ opts.on("-s", "--shared", "Show shared hooks") do
60
48
  options[:shared] = true
61
49
  end
62
- opts.on("-a", "--available", "Show available hooks") do
63
- options[:available] = true
50
+ opts.on("-u", "--uninstalled", "Show uninstalled hooks") do
51
+ options[:uninstalled] = true
64
52
  end
65
53
  end
66
54
  end
@@ -1,4 +1,4 @@
1
- class Gitty::Hook::Publish < Gitty::Runner
1
+ class Gitty::HookCommand::Publish < Gitty::Runner
2
2
  include ::Gitty::Helpers
3
3
 
4
4
  def run
@@ -1,5 +1,5 @@
1
1
  require 'fileutils'
2
- class Gitty::Hook::Shell < Gitty::Runner
2
+ class Gitty::HookCommand::Shell < Gitty::Runner
3
3
  include ::Gitty::Helpers
4
4
 
5
5
  def run
@@ -0,0 +1,39 @@
1
+ class Gitty::HookCommand::Uninstall < Gitty::Runner
2
+ include FileUtils
3
+ def initialize(args, stdout = STDOUT, stderr = STDERR)
4
+ super
5
+ @hookname = args.shift
6
+ end
7
+
8
+ def run
9
+ options = {:installed => true}
10
+ options[:install_kind] = options[:kind] if options[:kind]
11
+ hook = Gitty::Hook.find(@hookname, options)
12
+ return no_hook_found unless hook
13
+ hook.uninstall
14
+
15
+ stdout.puts "#{hook.install_kind} hook #{hook.name} has been successfully uninstalled."
16
+ if hook.install_kind == :shared
17
+ stdout.puts "To propagate this change other developers, run 'git hook publish -m \"removed #{hook.name}\""
18
+ end
19
+ end
20
+
21
+ protected
22
+
23
+ def no_hook_found
24
+ stderr.puts("there is no installed hook named '#{@hookname}'")
25
+ exit 1
26
+ end
27
+
28
+ def options
29
+ @options ||= super.update(:kind => :local)
30
+ end
31
+
32
+ def option_parser
33
+ @option_parser ||= super.tap do |opts|
34
+ opts.banner = "Usage: git hook uninstall [opts] hook-name"
35
+ opts.on("-l", "--local", "Local hook (default)") { |l| options[:kind] = :local }
36
+ opts.on("-s", "--shared", "Remote hook") { |l| options[:kind] = :shared }
37
+ end
38
+ end
39
+ end
@@ -18,4 +18,8 @@ module Gitty::Helpers
18
18
  def cmd(*args)
19
19
  system(*args.flatten)
20
20
  end
21
+
22
+ def search_for_file_in_paths(paths, file)
23
+
24
+ end
21
25
  end
@@ -1,42 +1,142 @@
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)
1
+ class Gitty::Hook
2
+ include Gitty::Helpers
3
+ include FileUtils
4
+ attr_accessor :path
5
+
6
+ def initialize(options = {})
7
+ options.each do |k,v|
8
+ send("#{k}=", v)
9
+ end
10
+ if installed?
11
+ extend Gitty::Hook::InstalledHookStrategy
18
12
  else
19
- parse_args!
13
+ extend Gitty::Hook::AvailableHookStrategy
20
14
  end
21
15
  end
22
-
23
- def option_parser
24
- @option_parser ||= super.tap do |opts|
25
- opts.banner = "Usage: git hook [command]\nCommands are: #{COMMANDS.join(', ')}"
16
+
17
+ def self.available_hooks_search_paths
18
+ Gitty.asset_paths.map { |ap| File.join(ap, "hooks") }
19
+ end
20
+
21
+ def self.installed_hooks_search_paths
22
+ [installed_hooks_path(:local), installed_hooks_path(:shared)]
23
+ end
24
+
25
+ def self.installed_path(which = :local)
26
+ Pathname.new(".git/hooks/#{which}")
27
+ end
28
+
29
+ def self.installed_hooks_path(which = :local)
30
+ installed_path(which) + "hooks"
31
+ end
32
+
33
+ def self.installed_helpers_path(which = :local)
34
+ installed_path(which) + "helpers"
35
+ end
36
+
37
+ def self.find_all(filters = {})
38
+ paths = installed_hooks_search_paths + available_hooks_search_paths
39
+ candidates = find_all_in_paths(paths)
40
+ filter_candidates(candidates, filters)
41
+ end
42
+
43
+ def self.filter_candidates(candidates, filters = {})
44
+ filters.each do |field, value|
45
+ candidates = candidates.select { |c| c.send(field) == value }
46
+ end
47
+ candidates
48
+ end
49
+
50
+ def self.find(name, options)
51
+ find_all(options.merge(:name => name)).first
52
+ end
53
+
54
+ def self.find_all_in_paths(paths)
55
+ paths.map { |hook_path| Dir.glob(File.join(hook_path, "*")) }.flatten.map do |path|
56
+ Gitty::Hook.new(:path => path)
26
57
  end
27
58
  end
28
59
 
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
60
+ def self.extract_meta_data(string_or_io)
61
+ io = string_or_io.respond_to?(:readline) ? string_or_io : StringIO.new(string_or_io)
62
+ meta_yaml = ""
63
+ begin
64
+ while line = io.readline
65
+ next unless line.match(/^# (description.+)/)
66
+ meta_yaml = "#{$1}\n"
67
+ break
68
+ end
69
+
70
+ while line = io.readline
71
+ break unless line.match(/^#()$/) || line.match(/^# (.*?)$/)
72
+ meta_yaml << "#{$1}\n"
73
+ end
74
+ rescue EOFError
33
75
  end
34
- @target && @target.run
76
+ meta_yaml.empty? ? nil : YAML.load(meta_yaml)
35
77
  end
36
78
 
37
- def parse_args!
38
- opt_p = option_parser
39
- opt_p.parse!(args)
40
- puts opt_p
79
+ def installed?
80
+ install_kind ? true : false
41
81
  end
42
- end
82
+ alias installed installed?
83
+
84
+ def install_kind
85
+ case
86
+ when path.include?(self.class.installed_hooks_path(:local).to_s) then :local
87
+ when path.include?(self.class.installed_hooks_path(:shared).to_s) then :shared
88
+ end
89
+ end
90
+
91
+ def name
92
+ File.basename(path)
93
+ end
94
+
95
+ def <=>(other)
96
+ path <=> other.path
97
+ end
98
+
99
+ def meta_data
100
+ @meta_data ||= self.class.extract_meta_data(File.read(path))
101
+ end
102
+
103
+ module AvailableHookStrategy
104
+ def install(which = :local)
105
+ target_hook_path = existing_directory!(self.class.installed_hooks_path(which))
106
+ target_helper_path = existing_directory!(self.class.installed_helpers_path(which))
107
+ base_directory = self.class.installed_path(which)
108
+ cp(path, target_hook_path + name)
109
+ chmod(0755, target_hook_path + name)
110
+ meta_data["targets"].each do |target|
111
+ ln_s(
112
+ "../hooks/#{name}",
113
+ file_with_existing_directory!(base_directory + "#{target}.d" + name)
114
+ )
115
+ end
116
+ (meta_data["helpers"] || []).each do |helper|
117
+ cp(Gitty.find_asset("helpers/#{helper}"), target_helper_path + helper)
118
+ chmod(0755, target_helper_path + helper)
119
+ end
120
+ end
121
+
122
+ def uninstall
123
+ # do nothing
124
+ end
125
+ end
126
+
127
+ module InstalledHookStrategy
128
+ def install(which = :local)
129
+ # do nothing
130
+ end
131
+
132
+ def uninstall
133
+ target_hook_path = path
134
+ base_directory = self.class.installed_path(install_kind)
135
+ meta_data["targets"].each { |target| rm_f(base_directory + "#{target}.d" + name) }
136
+ rm(target_hook_path)
137
+ # TODO - clean up helpers
138
+ end
139
+ end
140
+
141
+ private :path=
142
+ end
@@ -0,0 +1,42 @@
1
+ class Gitty::HookCommand < Gitty::Runner
2
+ COMMANDS = %w[
3
+ init
4
+ list
5
+ install
6
+ uninstall
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::HookCommand.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,139 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe Gitty::Hook do
4
+ def installed_hook(name, which = :local)
5
+ hook = Gitty::Hook.find(name, :installed => false)
6
+ hook.install(which)
7
+ Gitty::Hook.find(name, :installed => true)
8
+ end
9
+
10
+ before(:each) do
11
+ Gitty::Hook.stub!(:available_hooks_search_paths).and_return([SandboxWorld::GITTY_ASSETS + "hooks"])
12
+ create_file(SandboxWorld::GITTY_ASSETS + "hooks/submodule_updater", <<-EOF)
13
+ #!/bin/bash
14
+ # description: managers submodule updating for you
15
+ # targets: ["post-checkout", "post-merge"]
16
+ ...
17
+ EOF
18
+ create_file(SandboxWorld::GITTY_ASSETS + "hooks/no_messy_whitespace", <<-EOF)
19
+ #!/bin/bash
20
+ # description: prevents you from committing messy whitespace
21
+ # targets: ["pre-commit"]
22
+ ...
23
+ EOF
24
+ end
25
+
26
+ describe ".extract_meta_data" do
27
+ it "extracts meta data from a stream" do
28
+ stream = <<-EOF
29
+ #!/usr/bash
30
+
31
+ # description: |-
32
+ # hi
33
+ #
34
+ # bye
35
+ # targets: ["post-merge", "post-checkout"]
36
+ #
37
+
38
+ here's my hook
39
+ EOF
40
+ Gitty::Hook.extract_meta_data(stream).should == {
41
+ "description" => "hi\n\nbye",
42
+ "targets" => ["post-merge", "post-checkout"]
43
+ }
44
+ end
45
+
46
+ it "returns nil when no data found" do
47
+ stream = <<-EOF
48
+ #!/usr/bash
49
+ #
50
+ #
51
+ EOF
52
+ Gitty::Hook.extract_meta_data(stream).should == nil
53
+ end
54
+
55
+ it "returns the data when there's no actual content" do
56
+ stream = <<-EOF
57
+ #!/usr/bash
58
+ #
59
+ # description: hi
60
+ EOF
61
+ Gitty::Hook.extract_meta_data(stream).should == {"description" => "hi"}
62
+ end
63
+ end
64
+ describe ".find_all" do
65
+ it "returns all available hooks" do
66
+ Gitty::Hook.find_all(:installed => false).map(&:name).should == %w[no_messy_whitespace submodule_updater]
67
+ end
68
+ end
69
+
70
+ describe ".find" do
71
+ it "returns an available hook by name" do
72
+ Gitty::Hook.find("submodule_updater", :installed => false).name.should == "submodule_updater"
73
+ Gitty::Hook.find("no_messy_whitespace", :installed => false).name.should == "no_messy_whitespace"
74
+ end
75
+
76
+ it "finds installed hooks" do
77
+ end
78
+ end
79
+
80
+ describe "#installed?" do
81
+ it "returns false if the hook is not installed" do
82
+ Gitty::Hook.find("submodule_updater", :installed => false).installed?.should be_false
83
+ end
84
+
85
+ it "returns true if the hook is installed" do
86
+ Gitty::Hook.find("submodule_updater", :installed => false).install(:local)
87
+ Gitty::Hook.find("submodule_updater", :installed => true).installed?.should == true
88
+ end
89
+ end
90
+
91
+ describe "#install_kind" do
92
+ it "returns :local for local hooks" do
93
+ installed_hook("submodule_updater", :local).install_kind.should == :local
94
+ end
95
+
96
+ it "returns :shared for shared hooks" do
97
+ installed_hook("submodule_updater", :shared).install_kind.should == :shared
98
+ end
99
+ end
100
+
101
+ describe "#meta_data" do
102
+ it "reads the meta_data of a given file" do
103
+ Gitty::Hook.find("submodule_updater", :installed => false).meta_data
104
+ end
105
+ end
106
+
107
+ describe "#install" do
108
+ it "copies an available hook to the install path and links it into the targets" do
109
+ @hook = Gitty::Hook.find("submodule_updater", :installed => false)
110
+ @hook.install
111
+ File.exist?(".git/hooks/local/hooks/submodule_updater").should be_true
112
+ File.executable?(".git/hooks/local/hooks/submodule_updater").should be_true
113
+ File.exist?(".git/hooks/local/post-checkout.d/submodule_updater").should be_true
114
+ File.exist?(".git/hooks/local/post-merge.d/submodule_updater").should be_true
115
+ end
116
+
117
+ it "installs a hook into shared" do
118
+ @hook = Gitty::Hook.find("submodule_updater", :installed => false)
119
+ @hook.install(:shared)
120
+ File.exist?(".git/hooks/shared/hooks/submodule_updater").should be_true
121
+ File.executable?(".git/hooks/shared/hooks/submodule_updater").should be_true
122
+ File.exist?(".git/hooks/shared/post-checkout.d/submodule_updater").should be_true
123
+ File.exist?(".git/hooks/shared/post-merge.d/submodule_updater").should be_true
124
+ end
125
+ end
126
+
127
+ describe "#uninstall" do
128
+ it "removes a hook from installed path" do
129
+ hook = installed_hook("submodule_updater")
130
+ File.exist?(".git/hooks/local/hooks/submodule_updater").should be_true
131
+ File.symlink?(".git/hooks/local/post-checkout.d/submodule_updater").should be_true
132
+ File.symlink?(".git/hooks/local/post-merge.d/submodule_updater").should be_true
133
+ hook.uninstall
134
+ File.exist?(".git/hooks/local/hooks/submodule_updater").should be_false
135
+ File.symlink?(".git/hooks/local/post-checkout.d/submodule_updater").should be_false
136
+ File.symlink?(".git/hooks/local/post-merge.d/submodule_updater").should be_false
137
+ end
138
+ end
139
+ end
@@ -21,39 +21,4 @@ describe Gitty do
21
21
  end
22
22
  end
23
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
24
  end
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format
3
+ nested
4
+ --diff
5
+ --loadby
6
+ mtime
7
+ --drb
@@ -1,6 +1,29 @@
1
1
  require File.dirname(__FILE__) + "/../lib/gitty"
2
- SPEC_PATH = GITTY_ROOT_PATH + "spec"
3
2
  require 'rubygems'
4
- require 'cucumber'
3
+ require "spec"
4
+ SPEC_PATH = Pathname.new(File.dirname(__FILE__))
5
+ require SPEC_PATH + "../features/support/sandbox_world.rb"
5
6
  require SPEC_PATH + "support/constants.rb"
6
- require "spec"
7
+
8
+
9
+ require 'forwardable'
10
+ Spec::Runner.configure do |config|
11
+ extend Forwardable
12
+ def sandbox
13
+ @sandbox ||= SandboxWorld.new
14
+ end
15
+
16
+ [:run, :in_dir, :current_dir, :create_file, :last_exit_status, :last_stderr, :last_stdout, :reset_sandbox!].each do |m|
17
+ eval "def #{m}(*args) sandbox.send(:#{m}, *args) end"
18
+ end
19
+
20
+ config.before(:each) do
21
+ reset_sandbox!
22
+ @_original_dir = Dir.pwd
23
+ Dir.chdir(current_dir)
24
+ end
25
+
26
+ config.after(:each) do
27
+ Dir.chdir(@_original_dir)
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Harper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-21 00:00:00 -07:00
12
+ date: 2010-02-24 00:00:00 -08:00
13
13
  default_executable: git-hook
14
14
  dependencies: []
15
15
 
@@ -32,27 +32,28 @@ files:
32
32
  - assets/helpers/git-trash
33
33
  - assets/helpers/git-when-introduced
34
34
  - assets/helpers/hookd_wrapper
35
+ - assets/hooks/auto-submodules
35
36
  - assets/hooks/clean-patches
36
- - assets/hooks/git-post-checkout-submodules
37
37
  - assets/hooks/git-prevent-messy-rebase
38
- - assets/hooks/prevent-nocommit-tags
38
+ - assets/hooks/nocommit
39
39
  - bin/git-hook
40
40
  - cucumber.yml
41
41
  - lib/ext.rb
42
42
  - lib/gitty.rb
43
- - lib/gitty/commands/add.rb
44
43
  - lib/gitty/commands/init.rb
44
+ - lib/gitty/commands/install.rb
45
45
  - lib/gitty/commands/list.rb
46
- - lib/gitty/commands/manager.rb
47
46
  - lib/gitty/commands/publish.rb
48
- - lib/gitty/commands/remove.rb
49
47
  - lib/gitty/commands/shell.rb
48
+ - lib/gitty/commands/uninstall.rb
50
49
  - lib/gitty/helpers.rb
51
50
  - lib/gitty/hook.rb
51
+ - lib/gitty/hook_command.rb
52
52
  - lib/gitty/runner.rb
53
53
  - lib/string.rb
54
- - spec/gitty/commands/add_spec.rb
54
+ - spec/gitty/hook_spec.rb
55
55
  - spec/gitty_spec.rb
56
+ - spec/spec.opts
56
57
  - spec/spec_helper.rb
57
58
  - spec/support/constants.rb
58
59
  has_rdoc: true
@@ -84,7 +85,7 @@ signing_key:
84
85
  specification_version: 3
85
86
  summary: Unobtrusively extend git
86
87
  test_files:
87
- - spec/gitty/commands/add_spec.rb
88
+ - spec/gitty/hook_spec.rb
88
89
  - spec/gitty_spec.rb
89
90
  - spec/spec_helper.rb
90
91
  - spec/support/constants.rb
@@ -1,26 +0,0 @@
1
- require GITTY_PATH + "commands/manager"
2
-
3
- class Gitty::Hook::Add < Gitty::Hook::Manager
4
- include FileUtils
5
-
6
- def run
7
- cp(src_hook_file, master_hook_file)
8
- chmod(0755, master_hook_file)
9
- meta_data["targets"].each do |target|
10
- ln_s(
11
- "../hooks/#{@hookname}",
12
- file_with_existing_directory!(base_directory + "#{target}.d" + @hookname)
13
- )
14
- end
15
- (meta_data["helpers"] || []).each do |helper|
16
- cp(Gitty.find_asset("helpers/#{helper}"), helpers_directory + helper)
17
- chmod(0755, helpers_directory + helper)
18
- end
19
- end
20
-
21
- def option_parser
22
- @option_parser ||= super.tap do |opts|
23
- opts.banner = "Usage: git hook add [opts] hook-name"
24
- end
25
- end
26
- end
@@ -1,50 +0,0 @@
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
@@ -1,17 +0,0 @@
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
@@ -1,5 +0,0 @@
1
- require File.expand_path('../../spec_helper', File.dirname(__FILE__))
2
- require 'stringio'
3
-
4
- describe Gitty::Hook::Add do
5
- end