auto_tagger 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +4 -1
  2. data/CHANGELOG +26 -2
  3. data/Gemfile +4 -4
  4. data/Gemfile.lock +60 -0
  5. data/README.md +90 -36
  6. data/Rakefile +1 -26
  7. data/VERSION +1 -1
  8. data/auto_tagger.gemspec +24 -14
  9. data/bin/autotag +14 -29
  10. data/features/autotag.feature +43 -2
  11. data/features/deployment.feature +4 -0
  12. data/features/step_definitions/autotag_steps.rb +27 -22
  13. data/features/step_definitions/deployment_steps.rb +41 -33
  14. data/features/support/env.rb +45 -2
  15. data/features/support/step_helpers.rb +36 -12
  16. data/features/templates/deploy.erb +1 -1
  17. data/lib/auto_tagger/base.rb +150 -19
  18. data/lib/auto_tagger/capistrano_helper.rb +38 -17
  19. data/lib/auto_tagger/command_line.rb +65 -0
  20. data/lib/auto_tagger/commander.rb +22 -11
  21. data/lib/auto_tagger/configuration.rb +88 -0
  22. data/lib/auto_tagger/deprecator.rb +11 -0
  23. data/lib/auto_tagger/git/ref.rb +34 -0
  24. data/lib/auto_tagger/git/ref_set.rb +35 -0
  25. data/lib/auto_tagger/git/repo.rb +76 -0
  26. data/lib/auto_tagger/options.rb +170 -0
  27. data/lib/auto_tagger/recipes.rb +67 -27
  28. data/lib/auto_tagger.rb +9 -4
  29. data/spec/auto_tagger/base_spec.rb +236 -52
  30. data/spec/auto_tagger/capistrano_helper_spec.rb +82 -112
  31. data/spec/auto_tagger/command_line_spec.rb +110 -0
  32. data/spec/auto_tagger/commander_spec.rb +33 -7
  33. data/spec/auto_tagger/configuration_spec.rb +275 -0
  34. data/spec/auto_tagger/git/ref_set_spec.rb +61 -0
  35. data/spec/auto_tagger/git/ref_spec.rb +46 -0
  36. data/spec/auto_tagger/git/repo_spec.rb +108 -0
  37. data/spec/auto_tagger/options_spec.rb +157 -0
  38. data/spec/spec_helper.rb +1 -6
  39. metadata +32 -15
  40. data/geminstaller.yml +0 -7
  41. data/lib/auto_tagger/repository.rb +0 -43
  42. data/lib/auto_tagger/stage_manager.rb +0 -23
  43. data/lib/auto_tagger/tag.rb +0 -43
  44. data/spec/auto_tagger/repository_spec.rb +0 -72
  45. data/spec/auto_tagger/stage_manager_spec.rb +0 -34
  46. data/spec/auto_tagger/tag_spec.rb +0 -66
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe AutoTagger::Options do
4
+
5
+ shared_examples_for "common options" do
6
+ it "understands --date-separator" do
7
+ options = AutoTagger::Options.from_command_line ["--date-separator=-"]
8
+ options[:date_separator].should == "-"
9
+ end
10
+
11
+ it "understands --remote" do
12
+ options = AutoTagger::Options.from_command_line ["--remote=origin"]
13
+ options[:remote].should == "origin"
14
+ end
15
+
16
+ it "understands --ref-path" do
17
+ options = AutoTagger::Options.from_command_line ["--ref-path=tags"]
18
+ options[:ref_path].should == "tags"
19
+ end
20
+
21
+ it "understands --stages" do
22
+ options = AutoTagger::Options.from_command_line ["--stages=foo,bar,baz"]
23
+ options[:stages].should == "foo,bar,baz"
24
+ end
25
+
26
+ it "understands --refs-to-keep" do
27
+ options = AutoTagger::Options.from_command_line ["--refs-to-keep=4"]
28
+ options[:refs_to_keep].should == 4
29
+ end
30
+
31
+ it "understands --dry-run" do
32
+ options = AutoTagger::Options.from_command_line ["--dry-run"]
33
+ options[:dry_run].should be_true
34
+
35
+ options = AutoTagger::Options.from_command_line ["--dry-run=true"]
36
+ options[:dry_run].should be_true
37
+
38
+ options = AutoTagger::Options.from_command_line ["--dry-run=false"]
39
+ options[:dry_run].should be_false
40
+ end
41
+
42
+ it "understands --fetch-refs" do
43
+ options = AutoTagger::Options.from_command_line ["--fetch-refs=true"]
44
+ options[:fetch_refs].should == true
45
+
46
+ options = AutoTagger::Options.from_command_line ["--fetch-refs=false"]
47
+ options[:fetch_refs].should == false
48
+ end
49
+
50
+ it "understands --push-refs" do
51
+ options = AutoTagger::Options.from_command_line ["--push-refs=true"]
52
+ options[:push_refs].should == true
53
+
54
+ options = AutoTagger::Options.from_command_line ["--push-refs=false"]
55
+ options[:push_refs].should == false
56
+ end
57
+
58
+ it "understands --offline" do
59
+ options = AutoTagger::Options.from_command_line ["--offline"]
60
+ options[:offline].should be_nil
61
+
62
+ options = AutoTagger::Options.from_command_line ["--offline=true"]
63
+ options[:offline].should be_true
64
+ end
65
+ end
66
+
67
+ describe "#from_command_line" do
68
+
69
+ it_should_behave_like "common options"
70
+
71
+ it "takes the first argument to be the stage" do
72
+ options = AutoTagger::Options.from_command_line ["ci"]
73
+ options[:stage].should == "ci"
74
+ end
75
+
76
+ it "takes the second argument to be the path" do
77
+ options = AutoTagger::Options.from_command_line ["ci", "../"]
78
+ options[:path].should == "../"
79
+ end
80
+
81
+ it "understands --opts-file" do
82
+ options = AutoTagger::Options.from_command_line ["--opts-file=foo"]
83
+ options[:opts_file].should == "foo"
84
+ end
85
+
86
+ it "understands all help options" do
87
+ options = AutoTagger::Options.from_command_line ["ci"]
88
+ options[:show_help].should be_nil
89
+
90
+ options = AutoTagger::Options.from_command_line ["help"]
91
+ options[:show_help].should == true
92
+
93
+ options = AutoTagger::Options.from_command_line ["-h"]
94
+ options[:show_help].should == true
95
+
96
+ options = AutoTagger::Options.from_command_line ["--help"]
97
+ options[:show_help].should == true
98
+
99
+ options = AutoTagger::Options.from_command_line ["-?"]
100
+ options[:show_help].should == true
101
+
102
+ options = AutoTagger::Options.from_command_line []
103
+ options[:show_help].should == true
104
+ end
105
+
106
+ it "understands --version" do
107
+ options = AutoTagger::Options.from_command_line ["ci"]
108
+ options[:show_version].should be_nil
109
+
110
+ options = AutoTagger::Options.from_command_line ["version"]
111
+ options[:show_version].should == true
112
+
113
+ options = AutoTagger::Options.from_command_line ["--version"]
114
+ options[:show_version].should == true
115
+
116
+ options = AutoTagger::Options.from_command_line ["-v"]
117
+ options[:show_version].should == true
118
+ end
119
+
120
+ it "chooses the right command" do
121
+ options = AutoTagger::Options.from_command_line ["config"]
122
+ options[:command].should == :config
123
+
124
+ options = AutoTagger::Options.from_command_line ["version"]
125
+ options[:command].should == :version
126
+
127
+ options = AutoTagger::Options.from_command_line ["help"]
128
+ options[:command].should == :help
129
+
130
+ options = AutoTagger::Options.from_command_line [""]
131
+ options[:command].should == :help
132
+
133
+ options = AutoTagger::Options.from_command_line ["cleanup"]
134
+ options[:command].should == :cleanup
135
+
136
+ options = AutoTagger::Options.from_command_line ["list"]
137
+ options[:command].should == :list
138
+
139
+ options = AutoTagger::Options.from_command_line ["create"]
140
+ options[:command].should == :create
141
+
142
+ options = AutoTagger::Options.from_command_line ["ci"]
143
+ options[:command].should == :create
144
+
145
+ options = AutoTagger::Options.from_command_line ["delete_locally"]
146
+ options[:command].should == :delete_locally
147
+
148
+ options = AutoTagger::Options.from_command_line ["delete_on_remote"]
149
+ options[:command].should == :delete_on_remote
150
+ end
151
+ end
152
+
153
+ describe "#from_file" do
154
+ it_should_behave_like "common options"
155
+ end
156
+
157
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,2 @@
1
- require 'spec'
2
- require 'rr'
1
+ require 'rspec'
3
2
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "auto_tagger"))
4
-
5
- Spec::Runner.configure do |config|
6
- config.mock_with :rr
7
- end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auto_tagger
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 23
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 1
8
- - 5
9
- version: 0.1.5
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jeff Dean
@@ -21,16 +22,18 @@ autorequire:
21
22
  bindir: bin
22
23
  cert_chain: []
23
24
 
24
- date: 2010-05-15 00:00:00 -04:00
25
+ date: 2010-09-10 00:00:00 -04:00
25
26
  default_executable: autotag
26
27
  dependencies:
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: capistrano
29
30
  prerelease: false
30
31
  requirement: &id001 !ruby/object:Gem::Requirement
32
+ none: false
31
33
  requirements:
32
34
  - - ">="
33
35
  - !ruby/object:Gem::Version
36
+ hash: 29
34
37
  segments:
35
38
  - 2
36
39
  - 5
@@ -51,6 +54,7 @@ files:
51
54
  - .gitignore
52
55
  - CHANGELOG
53
56
  - Gemfile
57
+ - Gemfile.lock
54
58
  - MIT-LICENSE
55
59
  - README.md
56
60
  - Rakefile
@@ -66,21 +70,27 @@ files:
66
70
  - features/templates/cap_ext_deploy.erb
67
71
  - features/templates/deploy.erb
68
72
  - features/templates/stage.erb
69
- - geminstaller.yml
70
73
  - lib/auto_tagger.rb
71
74
  - lib/auto_tagger/base.rb
72
75
  - lib/auto_tagger/capistrano_helper.rb
76
+ - lib/auto_tagger/command_line.rb
73
77
  - lib/auto_tagger/commander.rb
78
+ - lib/auto_tagger/configuration.rb
79
+ - lib/auto_tagger/deprecator.rb
80
+ - lib/auto_tagger/git/ref.rb
81
+ - lib/auto_tagger/git/ref_set.rb
82
+ - lib/auto_tagger/git/repo.rb
83
+ - lib/auto_tagger/options.rb
74
84
  - lib/auto_tagger/recipes.rb
75
- - lib/auto_tagger/repository.rb
76
- - lib/auto_tagger/stage_manager.rb
77
- - lib/auto_tagger/tag.rb
78
85
  - spec/auto_tagger/base_spec.rb
79
86
  - spec/auto_tagger/capistrano_helper_spec.rb
87
+ - spec/auto_tagger/command_line_spec.rb
80
88
  - spec/auto_tagger/commander_spec.rb
81
- - spec/auto_tagger/repository_spec.rb
82
- - spec/auto_tagger/stage_manager_spec.rb
83
- - spec/auto_tagger/tag_spec.rb
89
+ - spec/auto_tagger/configuration_spec.rb
90
+ - spec/auto_tagger/git/ref_set_spec.rb
91
+ - spec/auto_tagger/git/ref_spec.rb
92
+ - spec/auto_tagger/git/repo_spec.rb
93
+ - spec/auto_tagger/options_spec.rb
84
94
  - spec/spec_helper.rb
85
95
  has_rdoc: true
86
96
  homepage: http://github.com/zilkey/auto_tagger
@@ -92,31 +102,38 @@ rdoc_options:
92
102
  require_paths:
93
103
  - lib
94
104
  required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
95
106
  requirements:
96
107
  - - ">="
97
108
  - !ruby/object:Gem::Version
109
+ hash: 3
98
110
  segments:
99
111
  - 0
100
112
  version: "0"
101
113
  required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
102
115
  requirements:
103
116
  - - ">="
104
117
  - !ruby/object:Gem::Version
118
+ hash: 3
105
119
  segments:
106
120
  - 0
107
121
  version: "0"
108
122
  requirements: []
109
123
 
110
124
  rubyforge_project:
111
- rubygems_version: 1.3.6
125
+ rubygems_version: 1.3.7
112
126
  signing_key:
113
127
  specification_version: 3
114
128
  summary: Helps you automatically create tags for each stage in a multi-stage deploment and deploy from the latest tag from the previous environment
115
129
  test_files:
116
130
  - spec/auto_tagger/base_spec.rb
117
131
  - spec/auto_tagger/capistrano_helper_spec.rb
132
+ - spec/auto_tagger/command_line_spec.rb
118
133
  - spec/auto_tagger/commander_spec.rb
119
- - spec/auto_tagger/repository_spec.rb
120
- - spec/auto_tagger/stage_manager_spec.rb
121
- - spec/auto_tagger/tag_spec.rb
134
+ - spec/auto_tagger/configuration_spec.rb
135
+ - spec/auto_tagger/git/ref_set_spec.rb
136
+ - spec/auto_tagger/git/ref_spec.rb
137
+ - spec/auto_tagger/git/repo_spec.rb
138
+ - spec/auto_tagger/options_spec.rb
122
139
  - spec/spec_helper.rb
data/geminstaller.yml DELETED
@@ -1,7 +0,0 @@
1
- gems:
2
- - name: capistrano
3
- version: '>= 2.5.3'
4
- - name: capistrano-ext
5
- version: '>= 1.2.1'
6
- - name: activesupport
7
- version: '>= 2.3.2'
@@ -1,43 +0,0 @@
1
- module AutoTagger
2
- class NoPathProvidedError < StandardError; end
3
- class NoSuchPathError < StandardError; end
4
- class InvalidGitRepositoryError < StandardError; end
5
- class GitCommandFailedError < StandardError; end
6
-
7
- class Repository
8
- attr_reader :path
9
-
10
- def initialize(path)
11
- if path.to_s.strip == ""
12
- raise NoPathProvidedError
13
- elsif ! File.exists?(path)
14
- raise NoSuchPathError
15
- elsif ! File.exists?(File.join(path, ".git"))
16
- raise InvalidGitRepositoryError
17
- else
18
- @path = path
19
- end
20
- end
21
-
22
- def ==(other)
23
- other.is_a?(Repository) && other.path == path
24
- end
25
-
26
- def tags
27
- @tags ||= Tag.new(self)
28
- end
29
-
30
- def commit_for(tag)
31
- Commander.execute(path, "git --no-pager log #{tag} --pretty=oneline -1")
32
- end
33
-
34
- def run(cmd)
35
- Commander.execute(path, cmd)
36
- end
37
-
38
- def run!(cmd)
39
- Commander.execute?(path, cmd) || raise(GitCommandFailedError)
40
- end
41
-
42
- end
43
- end
@@ -1,23 +0,0 @@
1
- module AutoTagger
2
- class StageManager
3
- class NoStagesSpecifiedError < StandardError
4
- def message
5
- "You must set the :stages variable to an array, like set :stages, [:ci, :demo]"
6
- end
7
- end
8
-
9
- attr_reader :stages
10
-
11
- def initialize(stages)
12
- raise NoStagesSpecifiedError unless stages && stages.is_a?(Array)
13
- @stages = stages.map{|stage| stage.to_s }
14
- end
15
-
16
- def previous_stage(stage)
17
- if stage
18
- index = stages.index(stage.to_s) - 1
19
- stages[index] if index > -1
20
- end
21
- end
22
- end
23
- end
@@ -1,43 +0,0 @@
1
- # git --no-pager log --pretty=oneline -1
2
- # git tag -a -m 'Successful continuous integration build on #{timestamp}' #{tag_name}"
3
- module AutoTagger
4
- class Tag
5
-
6
- attr_reader :repository
7
-
8
- def initialize(repository)
9
- @repository = repository
10
- end
11
-
12
- def find_all
13
- repository.run("git tag").split("\n")
14
- end
15
-
16
- def fetch
17
- repository.run! "git fetch origin --tags"
18
- end
19
-
20
- def latest_from(stage)
21
- find_all.select{|tag| tag =~ /^#{stage}\//}.sort.last
22
- end
23
-
24
- def push
25
- repository.run! "git push origin --tags"
26
- end
27
-
28
- def create(stage, commit = nil)
29
- tag_name = name_for(stage)
30
- cmd = "git tag #{tag_name}"
31
- cmd += " #{commit}" if commit
32
- repository.run! cmd
33
- tag_name
34
- end
35
-
36
- private
37
-
38
- def name_for(stage)
39
- "%s/%s" % [stage, Time.now.utc.strftime('%Y%m%d%H%M%S')]
40
- end
41
-
42
- end
43
- end
@@ -1,72 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- describe AutoTagger::Repository do
4
- describe ".new" do
5
- it "sets the repo" do
6
- mock(File).exists?(anything).twice { true }
7
- repo = AutoTagger::Repository.new("/foo")
8
- repo.path.should == "/foo"
9
- end
10
-
11
- it "raises an error when the path is blank" do
12
- proc do
13
- AutoTagger::Repository.new(" ")
14
- end.should raise_error(AutoTagger::NoPathProvidedError)
15
- end
16
-
17
- it "raises an error when the path is nil" do
18
- proc do
19
- AutoTagger::Repository.new(nil)
20
- end.should raise_error(AutoTagger::NoPathProvidedError)
21
- end
22
-
23
- it "raises an error with a file that doesn't exist" do
24
- mock(File).exists?("/foo") { false }
25
- proc do
26
- AutoTagger::Repository.new("/foo")
27
- end.should raise_error(AutoTagger::NoSuchPathError)
28
- end
29
-
30
- it "raises an error with a non-git repository" do
31
- mock(File).exists?("/foo") { true }
32
- mock(File).exists?("/foo/.git") { false }
33
- proc do
34
- AutoTagger::Repository.new("/foo")
35
- end.should raise_error(AutoTagger::InvalidGitRepositoryError)
36
- end
37
- end
38
-
39
- describe "#==" do
40
- it "compares paths" do
41
- mock(File).exists?(anything).times(any_times) { true }
42
- AutoTagger::Repository.new("/foo").should_not == "/foo"
43
- AutoTagger::Repository.new("/foo").should_not == AutoTagger::Repository.new("/bar")
44
- AutoTagger::Repository.new("/foo").should == AutoTagger::Repository.new("/foo")
45
- end
46
- end
47
-
48
- describe "#run" do
49
- it "sends the correct command" do
50
- mock(File).exists?(anything).twice { true }
51
- mock(AutoTagger::Commander).execute("/foo", "bar")
52
- AutoTagger::Repository.new("/foo").run("bar")
53
- end
54
- end
55
-
56
- describe "run!" do
57
- it "sends the correct command" do
58
- mock(File).exists?(anything).twice { true }
59
- mock(AutoTagger::Commander).execute?("/foo", "bar") { true }
60
- AutoTagger::Repository.new("/foo").run!("bar")
61
- end
62
-
63
- it "raises an exception if it the command returns false" do
64
- mock(File).exists?(anything).twice { true }
65
- mock(AutoTagger::Commander).execute?("/foo", "bar") { false }
66
- proc do
67
- AutoTagger::Repository.new("/foo").run!("bar")
68
- end.should raise_error(AutoTagger::GitCommandFailedError)
69
- end
70
- end
71
-
72
- end
@@ -1,34 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- describe AutoTagger::StageManager do
4
-
5
- describe ".new" do
6
- [nil, ""].each do |value|
7
- it "blows up if there are stages == #{value.inspect}" do
8
- proc do
9
- AutoTagger::StageManager.new(value)
10
- end.should raise_error(AutoTagger::StageManager::NoStagesSpecifiedError)
11
- end
12
- end
13
- end
14
-
15
- describe "#previous_stage" do
16
- it "returns the previous stage as a string if there is more than one stage, and there is a current stage" do
17
- AutoTagger::StageManager.new([:foo, :bar]).previous_stage(:bar).should == "foo"
18
- end
19
-
20
- it "returns nil if there is no previous stage" do
21
- AutoTagger::StageManager.new([:bar]).previous_stage(:bar).should be_nil
22
- end
23
-
24
- it "deals with mixed strings and symbols" do
25
- AutoTagger::StageManager.new([:"foo-bar", "baz"]).previous_stage(:baz).should == "foo-bar"
26
- end
27
-
28
- it "returns nil if there is no current stage" do
29
- AutoTagger::StageManager.new([:bar]).previous_stage(nil).should be_nil
30
- end
31
- end
32
-
33
-
34
- end
@@ -1,66 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- describe AutoTagger::Tag do
4
-
5
- before(:each) do
6
- @repository = Object.new
7
- end
8
-
9
- describe ".new" do
10
- it "sets the repository" do
11
- AutoTagger::Tag.new(@repository).repository.should == @repository
12
- end
13
- end
14
-
15
- describe "#find_all" do
16
- it "returns an array of tags" do
17
- mock(@repository).run("git tag") { "ci_01\nci_02" }
18
- AutoTagger::Tag.new(@repository).find_all.should == ["ci_01", "ci_02"]
19
- end
20
-
21
- it "returns an empty array if there are none" do
22
- mock(@repository).run("git tag") { "" }
23
- AutoTagger::Tag.new(@repository).find_all.should be_empty
24
- end
25
- end
26
-
27
- describe "#latest_from" do
28
- before do
29
- @tag = AutoTagger::Tag.new(@repository)
30
- mock(@tag).find_all { ["ci/01", "ci/02"] }
31
- end
32
-
33
- it "returns the latest tag that starts with the specified stage" do
34
- @tag.latest_from(:ci).should == "ci/02"
35
- end
36
-
37
- it "returns nil if none match" do
38
- @tag.latest_from(:staging).should be_nil
39
- end
40
- end
41
-
42
- describe "#fetch_tags" do
43
- it "sends the correct command" do
44
- mock(@repository).run!("git fetch origin --tags")
45
- AutoTagger::Tag.new(@repository).fetch
46
- end
47
- end
48
-
49
- describe "#push" do
50
- it "sends the correct command" do
51
- mock(@repository).run!("git push origin --tags")
52
- AutoTagger::Tag.new(@repository).push
53
- end
54
- end
55
-
56
- describe "#create" do
57
- it "creates the right command and returns the name" do
58
- time = Time.local(2001,1,1)
59
- mock(Time).now.once {time}
60
- tag_name = "ci/#{time.utc.strftime('%Y%m%d%H%M%S')}"
61
- mock(@repository).run!("git tag #{tag_name}")
62
- AutoTagger::Tag.new(@repository).create("ci").should == tag_name
63
- end
64
- end
65
-
66
- end