tddium 1.25.5

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.
Files changed (48) hide show
  1. checksums.yaml +15 -0
  2. data/bin/tddium +29 -0
  3. data/lib/tddium.rb +19 -0
  4. data/lib/tddium/agent.rb +3 -0
  5. data/lib/tddium/agent/tddium.rb +122 -0
  6. data/lib/tddium/cli.rb +26 -0
  7. data/lib/tddium/cli/api.rb +319 -0
  8. data/lib/tddium/cli/commands/account.rb +49 -0
  9. data/lib/tddium/cli/commands/activate.rb +14 -0
  10. data/lib/tddium/cli/commands/config.rb +55 -0
  11. data/lib/tddium/cli/commands/describe.rb +96 -0
  12. data/lib/tddium/cli/commands/find_failing.rb +62 -0
  13. data/lib/tddium/cli/commands/github.rb +53 -0
  14. data/lib/tddium/cli/commands/heroku.rb +15 -0
  15. data/lib/tddium/cli/commands/hg.rb +48 -0
  16. data/lib/tddium/cli/commands/keys.rb +83 -0
  17. data/lib/tddium/cli/commands/login.rb +37 -0
  18. data/lib/tddium/cli/commands/logout.rb +14 -0
  19. data/lib/tddium/cli/commands/password.rb +26 -0
  20. data/lib/tddium/cli/commands/rerun.rb +50 -0
  21. data/lib/tddium/cli/commands/server.rb +22 -0
  22. data/lib/tddium/cli/commands/spec.rb +306 -0
  23. data/lib/tddium/cli/commands/status.rb +107 -0
  24. data/lib/tddium/cli/commands/stop.rb +19 -0
  25. data/lib/tddium/cli/commands/suite.rb +110 -0
  26. data/lib/tddium/cli/commands/web.rb +22 -0
  27. data/lib/tddium/cli/config.rb +245 -0
  28. data/lib/tddium/cli/params_helper.rb +36 -0
  29. data/lib/tddium/cli/prompt.rb +128 -0
  30. data/lib/tddium/cli/show.rb +122 -0
  31. data/lib/tddium/cli/suite.rb +179 -0
  32. data/lib/tddium/cli/tddium.rb +153 -0
  33. data/lib/tddium/cli/text_helper.rb +16 -0
  34. data/lib/tddium/cli/timeformat.rb +21 -0
  35. data/lib/tddium/cli/util.rb +132 -0
  36. data/lib/tddium/constant.rb +509 -0
  37. data/lib/tddium/scm.rb +8 -0
  38. data/lib/tddium/scm/git.rb +188 -0
  39. data/lib/tddium/scm/git_log_parser.rb +67 -0
  40. data/lib/tddium/scm/hg.rb +160 -0
  41. data/lib/tddium/scm/hg_log_parser.rb +66 -0
  42. data/lib/tddium/scm/scm.rb +20 -0
  43. data/lib/tddium/script.rb +12 -0
  44. data/lib/tddium/script/git-remote-hg +1258 -0
  45. data/lib/tddium/ssh.rb +66 -0
  46. data/lib/tddium/util.rb +35 -0
  47. data/lib/tddium/version.rb +5 -0
  48. metadata +394 -0
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
2
+
3
+ require 'tddium/scm/git_log_parser'
4
+ require 'tddium/scm/hg_log_parser'
5
+
6
+ require 'tddium/scm/scm'
7
+ require 'tddium/scm/git'
8
+ require 'tddium/scm/hg'
@@ -0,0 +1,188 @@
1
+ # Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
2
+
3
+ module Tddium
4
+ class Git
5
+ include TddiumConstant
6
+
7
+ def scm_name
8
+ return 'git'
9
+ end
10
+
11
+ def repo?
12
+ if File.directory?('.git') then
13
+ return true
14
+ end
15
+ ignore = `git status 2>&1`
16
+ ok = $?.success?
17
+ return ok
18
+ end
19
+
20
+ def root
21
+ root = `git rev-parse --show-toplevel 2>&1`
22
+ if $?.exitstatus == 0 then
23
+ root.chomp! if root
24
+ return root
25
+ end
26
+ return Dir.pwd
27
+ end
28
+
29
+ def mirror_path
30
+ return nil
31
+ end
32
+
33
+ def repo_name
34
+ return File.basename(self.root)
35
+ end
36
+
37
+ def origin_url
38
+ result = `(git config --get remote.origin.url || echo GIT_FAILED) 2>/dev/null`
39
+ return nil if result =~ /GIT_FAILED/
40
+ result.strip
41
+ end
42
+
43
+ def ignore_path
44
+ path = File.join(self.root, Config::GIT_IGNORE)
45
+ return path
46
+ end
47
+
48
+ def current_branch
49
+ `git symbolic-ref HEAD`.gsub("\n", "").split("/")[2..-1].join("/")
50
+ end
51
+
52
+ def default_branch
53
+ `git remote show origin | grep HEAD | awk '{print $3}'`.gsub("\n", "")
54
+ end
55
+
56
+ # XXX DANGER: This method will edit the current workspace. It's meant to
57
+ # be run to make a git mirror up-to-date.
58
+ def checkout(branch, options={})
59
+ if !!options[:update] then
60
+ `git fetch origin`
61
+ return false if !$?.success?
62
+ end
63
+
64
+ cmd = "git checkout "
65
+ if !!options[:force] then
66
+ cmd += "-f "
67
+ end
68
+ cmd += Shellwords.shellescape(branch)
69
+ `#{cmd}`
70
+
71
+ return false if !$?.success?
72
+
73
+ `git reset --hard origin/#{branch}`
74
+ return $?.success?
75
+ end
76
+
77
+ def changes?(options={})
78
+ return Tddium::Git.git_changes?(:exclude=>".gitignore")
79
+ end
80
+
81
+ def push_latest(session_data, suite_details, options={})
82
+ branch = options[:branch] || self.current_branch
83
+ remote_branch = options[:remote_branch] || branch
84
+ git_repo_uri = if options[:git_repo_uri] then
85
+ options[:git_repo_uri]
86
+ elsif options[:use_private_uri] then
87
+ suite_details["git_repo_private_uri"] || suite_details["git_repo_uri"]
88
+ else
89
+ suite_details["git_repo_uri"]
90
+ end
91
+ this_ref = (session_data['commit_data'] || {})['git_ref']
92
+ refs = this_ref ? ["HEAD:#{this_ref}"] : []
93
+
94
+ if options[:git_repo_origin_uri] then
95
+ Tddium::Git.git_set_remotes(options[:git_repo_origin_uri], 'origin')
96
+ end
97
+
98
+ Tddium::Git.git_set_remotes(git_repo_uri)
99
+ return Tddium::Git.git_push(branch, refs, remote_branch)
100
+ end
101
+
102
+ def current_commit
103
+ `git rev-parse --verify HEAD`.strip
104
+ end
105
+
106
+ def commits
107
+ commits = GitCommitLogParser.new(self.latest_commit).commits
108
+ return commits
109
+ end
110
+
111
+ def number_of_commits(id_from, id_to)
112
+ result = `git log --pretty='%H' #{id_from}..#{id_to}`
113
+ result.split("\n").length
114
+ end
115
+
116
+ protected
117
+
118
+ def latest_commit
119
+ `git log --pretty='%H%n%s%n%aN%n%aE%n%at%n%cN%n%cE%n%ct%n' HEAD^..HEAD`
120
+ end
121
+
122
+ class << self
123
+ include TddiumConstant
124
+
125
+ def git_changes?(options={})
126
+ options[:exclude] ||= []
127
+ options[:exclude] = [options[:exclude]] unless options[:exclude].is_a?(Array)
128
+ cmd = "(git status --porcelain -uno || echo GIT_FAILED) < /dev/null 2>&1"
129
+ p = IO.popen(cmd)
130
+ changes = false
131
+ while line = p.gets do
132
+ if line =~ /GIT_FAILED/
133
+ warn(Text::Warning::SCM_UNABLE_TO_DETECT)
134
+ return false
135
+ end
136
+ line = line.strip
137
+ status, name = line.split(/\s+/)
138
+ next if options[:exclude].include?(name)
139
+ if status !~ /^\?/ then
140
+ changes = true
141
+ break
142
+ end
143
+ end
144
+ return changes
145
+ end
146
+
147
+ def git_set_remotes(git_repo_uri, remote_name=nil)
148
+ remote_name ||= Config::REMOTE_NAME
149
+
150
+ unless `git remote show -n #{remote_name}` =~ /#{git_repo_uri}/
151
+ `git remote rm #{remote_name} > /dev/null 2>&1`
152
+ `git remote add #{remote_name} #{git_repo_uri.shellescape}`
153
+ end
154
+ end
155
+
156
+ def git_push(this_branch, additional_refs=[], remote_branch=nil)
157
+ say Text::Process::SCM_PUSH
158
+ remote_branch ||= this_branch
159
+ refs = ["#{this_branch}:#{remote_branch}"]
160
+ refs += additional_refs
161
+ refspec = refs.map(&:shellescape).join(" ")
162
+ cmd = "git push -f #{Config::REMOTE_NAME} #{refspec}"
163
+ say "Running '#{cmd}'"
164
+ system(cmd)
165
+ end
166
+
167
+ def version_ok
168
+ version = nil
169
+ begin
170
+ version_string = `git --version`
171
+ m = version_string.match(Dependency::VERSION_REGEXP)
172
+ version = m[0] unless m.nil?
173
+ rescue Errno
174
+ rescue Exception
175
+ end
176
+ if version.nil? || version.empty? then
177
+ abort Text::Error::SCM_NOT_FOUND
178
+ end
179
+ version_parts = version.split(".")
180
+ if version_parts[0].to_i < 1 ||
181
+ (version_parts[0].to_i < 2 && version_parts[1].to_i == 1 && version_parts[1].to_i < 7) then
182
+ warn(Text::Warning::GIT_VERSION % version)
183
+ end
184
+ true
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
2
+
3
+ # this is not namespaced under Tddium because we want to eventually move this out into another gem
4
+ class GitCommitLogParser
5
+ attr_accessor :commit_log
6
+
7
+ # example commit_log generated by
8
+ # `git log --pretty='%H%n%s%n%aN%n%aE%n%at%n%cN%n%cE%n%ct%n' HEAD^..HEAD`
9
+
10
+ # 15e8cbd88d68d210953d51c28e26c6b9944a313b
11
+ # ignore .ruby-version for rvm
12
+ # Bob Smith
13
+ # bob@example.com
14
+ # 1367556311
15
+ # Fred Smith
16
+ # fred@example.com
17
+ # 1367556311
18
+ #
19
+
20
+ def initialize(commit_log)
21
+ @commit_log = commit_log
22
+ end
23
+
24
+ # Returns a list of commits in the following format
25
+ # [{
26
+ # "id" => "15e8cbd88d68d210953d51c28e26c6b9944a313b",
27
+ # "author" => {"name"=>"Bob Smith", "email"=>"bob@example.com"},
28
+ # "committer" => {"name"=>"Fred Smith", "email"=>"fred@example.com"},
29
+ # "summary" => "ignore .ruby-version for rvm",
30
+ # "date" => 1380603292
31
+ # }]
32
+
33
+ def commits
34
+ record = []
35
+ commits = []
36
+ commit_log.lines.each do |line|
37
+ line.strip!
38
+ line.sanitize!
39
+ if line.empty?
40
+ c = parse_commit(record)
41
+ commits.push(c)
42
+ record = []
43
+ else
44
+ record.push(line)
45
+ end
46
+ end
47
+
48
+ commits
49
+ end
50
+
51
+ private
52
+
53
+ def parse_commit(record)
54
+ time = record[4].to_i
55
+ author = build_user(record[2], record[3])
56
+ committer = build_user(record[5], record[6])
57
+ build_commit(record[0], author, committer, record[1], time)
58
+ end
59
+
60
+ def build_user(name, email)
61
+ {"name" => name, "email" => email}
62
+ end
63
+
64
+ def build_commit(sha, author, committer, summary, date)
65
+ {"id" => sha, "author" => author, "committer" => committer, "summary" => summary, "date" => date}
66
+ end
67
+ end
@@ -0,0 +1,160 @@
1
+ # Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
2
+
3
+ require 'uri'
4
+ require 'shellwords'
5
+
6
+ module Tddium
7
+ class Hg
8
+ include TddiumConstant
9
+
10
+ def scm_name
11
+ return 'hg'
12
+ end
13
+
14
+ def repo?
15
+ if File.directory?('.hg') then
16
+ return true
17
+ end
18
+ ignore = `hg status 2>&1`
19
+ ok = $?.success?
20
+ return ok
21
+ end
22
+
23
+ def root
24
+ root = `hg root`
25
+ if $?.exitstatus == 0 then
26
+ root.chomp! if root
27
+ return root
28
+ end
29
+ return Dir.pwd
30
+ end
31
+
32
+ def repo_name
33
+ return File.basename(self.root)
34
+ end
35
+
36
+ def origin_url
37
+ result = `(hg paths default || echo HG_FAILED) 2>/dev/null`
38
+ return nil if result =~ /HG_FAILED/
39
+ result.strip!
40
+ u = URI.parse(result) rescue nil
41
+ if u && u.host.nil? then
42
+ warn(Text::Warning::HG_PATHS_DEFAULT_NOT_URI)
43
+ return nil
44
+ end
45
+ return result
46
+ end
47
+
48
+ def ignore_path
49
+ path = File.join(self.root, Config::HG_IGNORE)
50
+ return path
51
+ end
52
+
53
+ def current_branch
54
+ branch = `hg branch`
55
+ branch.chomp!
56
+ return branch
57
+ end
58
+
59
+ def default_branch
60
+ # NOTE: not necessarily quite right in HG 2.1+ with a default bookmark
61
+ return "default"
62
+ end
63
+
64
+ def changes?(options={})
65
+ return Tddium::Hg.hg_changes?(:exclude=>".hgignore")
66
+ end
67
+
68
+ def hg_push(uri)
69
+ cmd = "hg push -f -b #{self.current_branch} "
70
+ cmd += " #{uri}"
71
+
72
+ # git outputs something to stderr when it runs git push.
73
+ # hg doesn't always ... so show the command that's being run and its
74
+ # output to indicate progress.
75
+ puts cmd
76
+ puts `#{cmd}`
77
+ return [0,1].include?( $?.exitstatus )
78
+ end
79
+
80
+ def push_latest(session_data, suite_details, options={})
81
+ uri = if options[:use_private_uri] then
82
+ suite_details["git_repo_private_uri"] || suite_details["git_repo_uri"]
83
+ else
84
+ suite_details["git_repo_uri"]
85
+ end
86
+ self.hg_push(uri)
87
+ end
88
+
89
+ def current_commit
90
+ commit = `hg id -i`
91
+ commit.chomp!
92
+ return commit
93
+ end
94
+
95
+ def commits
96
+ commits = HgCommitLogParser.new(self.latest_commit).commits
97
+ return commits
98
+ end
99
+
100
+ def number_of_commits(id_from, id_to)
101
+ result = `hg log --template='{node}\\n' #{id_from}..#{id_to}`
102
+ result.split("\n").length
103
+ end
104
+
105
+ protected
106
+
107
+ def latest_commit
108
+ `hg log -f -l 1 --template='{node}\\n{desc|firstline}\\n{author|user}\\n{author|email}\\n{date}\\n{author|user}\\n{author|email}\\n{date}\\n\\n'`
109
+ end
110
+
111
+ class << self
112
+ include TddiumConstant
113
+
114
+ def hg_changes?(options={})
115
+ options[:exclude] ||= []
116
+ options[:exclude] = [options[:exclude]] unless options[:exclude].is_a?(Array)
117
+ cmd = "(hg status -mardu || echo HG_FAILED) < /dev/null 2>&1"
118
+ p = IO.popen(cmd)
119
+ changes = false
120
+ while line = p.gets do
121
+ if line =~ /HG_FAILED/
122
+ warn(Text::Warning::SCM_UNABLE_TO_DETECT)
123
+ return false
124
+ end
125
+ line = line.strip
126
+ status, name = line.split(/\s+/)
127
+ next if options[:exclude].include?(name)
128
+ if status !~ /^\?/ then
129
+ changes = true
130
+ break
131
+ end
132
+ end
133
+ return changes
134
+ end
135
+
136
+ def hg_push(this_branch, additional_refs=[])
137
+ raise "not implemented"
138
+ end
139
+
140
+ def version_ok
141
+ version = nil
142
+ begin
143
+ version_string = `hg -q --version`
144
+ m = version_string.match(Dependency::VERSION_REGEXP)
145
+ version = m[0] unless m.nil?
146
+ rescue Errno
147
+ rescue Exception
148
+ end
149
+ if version.nil? || version.empty? then
150
+ abort Text::Error::SCM_NOT_FOUND
151
+ end
152
+ version_parts = version.split(".")
153
+ if version_parts[0].to_i < 2 then
154
+ warn(Text::Warning::HG_VERSION % version)
155
+ end
156
+ true
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
2
+
3
+ # this is not namespaced under Tddium because we want to eventually move this out into another gem
4
+ class HgCommitLogParser
5
+ attr_accessor :commit_log
6
+
7
+ # example commit_log generated by
8
+ # `hg log -f -l 1 --template='{node}\n{desc|firstline}\n{author|user}\n{author|email}\n{date}\n{author|user}\n{author|email}\n{date}\n'`
9
+
10
+ # beb3d918995bbe6370bb21fd76b4f433bfd64dc4
11
+ # commit summary
12
+ # user
13
+ # user@host.domain
14
+ # 1399437808.00
15
+ # user
16
+ # user@host.domain
17
+ # 1399437808.00
18
+
19
+ def initialize(commit_log)
20
+ @commit_log = commit_log
21
+ end
22
+
23
+ # Returns a list of commits in the following format
24
+ # [{
25
+ # "id" => "15e8cbd88d68d210953d51c28e26c6b9944a313b",
26
+ # "author" => {"name"=>"Bob Smith", "email"=>"bob@example.com"},
27
+ # "committer" => {"name"=>"Fred Smith", "email"=>"fred@example.com"},
28
+ # "summary" => "ignore .ruby-version for rvm",
29
+ # "date" => 1380603292
30
+ # }]
31
+
32
+ def commits
33
+ record = []
34
+ commits = []
35
+ commit_log.lines.each do |line|
36
+ line.strip!
37
+ line.sanitize!
38
+ if line.empty?
39
+ c = parse_commit(record)
40
+ commits.push(c)
41
+ record = []
42
+ else
43
+ record.push(line)
44
+ end
45
+ end
46
+
47
+ commits
48
+ end
49
+
50
+ private
51
+
52
+ def parse_commit(record)
53
+ time = record[4].to_i
54
+ author = build_user(record[2], record[3])
55
+ committer = build_user(record[5], record[6])
56
+ build_commit(record[0], author, committer, record[1], time)
57
+ end
58
+
59
+ def build_user(name, email)
60
+ {"name" => name, "email" => email}
61
+ end
62
+
63
+ def build_commit(sha, author, committer, summary, date)
64
+ {"id" => sha, "author" => author, "committer" => committer, "summary" => summary, "date" => date}
65
+ end
66
+ end