gitty 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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