heidi 0.0.4 → 0.1.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.
data/README.rdoc CHANGED
@@ -93,6 +93,35 @@ Any build is named after it's commit hash (5f6db178c for instance)
93
93
  Any successful integration attempt is stored in a tar-ball with the name of
94
94
  the build (5f6db178c.tar.bz2) inside projects/$project/logs/$build/
95
95
 
96
+ == Locking
97
+
98
+ Heidi locks the projects she's working on. Letting two Heidi's onto the
99
+ mountain should not be a problem. If you believe a project's lock is stale
100
+ just remove projects/$project/.lock
101
+
102
+ == Integrating
103
+
104
+ With crontab for instance...
105
+
106
+ PATH=$PATH:/usr/local/bin
107
+ MAILTO=icann@example.org
108
+
109
+ # m h dom mon dow command
110
+ */5 * * * 1-6 cd /path/to/heidi_root && bundle exec heidi integrate
111
+
112
+ Or by hand
113
+
114
+ heidi integrate [$project]
115
+
116
+ == Results
117
+
118
+ And off course you would like to see some results...
119
+
120
+ % cd /path/to/heidi
121
+ % heidi_web
122
+
123
+ Just make sure to set your firewall straight
124
+
96
125
  == Contributing to heidi
97
126
 
98
127
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.1.0
data/bin/heidi CHANGED
@@ -6,6 +6,8 @@ require 'heidi'
6
6
  cmd = ARGV.shift
7
7
  for_a = ARGV.shift
8
8
 
9
+ ENV['PATH'] = "/bin:/usr/bin:/usr/local/bin"
10
+
9
11
  shell = SimpleShell.new
10
12
 
11
13
  def check_heidi_root()
@@ -58,8 +60,17 @@ when "project"
58
60
  cached.git %W(config heidi.name #{for_a})
59
61
  end
60
62
  end
63
+ puts "Creating default test hook: projects/#{for_a}/hooks/test/01_rspec"
64
+ File.open("projects/#{for_a}/hooks/tests/01_rspec", File::CREAT|File::WRONLY) do |f|
65
+ f.puts %q(#!/bin/sh
66
+
67
+ # edit this file to your needs
68
+ bundle exec rake spec
69
+ )
70
+ end
71
+ shell.chmod %W(+x projects/#{for_a}/hooks/test/01_rspec)
61
72
  puts "\n"
62
- puts "Now define some hooks in projects/#{for_a}/hooks/tests"
73
+ puts "Now edit or add some hooks and run: heidi integrate #{for_a}"
63
74
 
64
75
  when "drop"
65
76
  check_heidi_root
@@ -80,7 +91,7 @@ when "integrate"
80
91
  next if !for_a.nil? && project.name != for_a
81
92
  project.fetch
82
93
  msg = project.integrate
83
- unless msg.nil?
94
+ unless msg.nil? || msg == true
84
95
  $stderr.puts "#{project.name}: #{msg}"
85
96
  end
86
97
  end
data/heidi.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "heidi"
8
- s.version = "0.0.4"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Hartog C. de Mik"]
data/lib/heidi/build.rb CHANGED
@@ -105,6 +105,7 @@ class Heidi
105
105
  end
106
106
 
107
107
  def unlock
108
+ return unless locked?
108
109
  log(:info, "Unlocking build")
109
110
  File.unlink lock_file
110
111
  end
@@ -148,8 +149,12 @@ class Heidi
148
149
  "DNF"
149
150
  end
150
151
 
151
- def create_tar_ball
152
- # TODO
152
+ # file handle to tar ball
153
+ def tar_ball
154
+ ball = File.join(@root, "#{commit}.tar.bz2")
155
+
156
+ return nil if !File.exists?(ball)
157
+ return File.open(ball, File::RDONLY)
153
158
  end
154
159
 
155
160
  class Logs
data/lib/heidi/builder.rb CHANGED
@@ -82,7 +82,7 @@ class Heidi
82
82
 
83
83
  def create_tar_ball
84
84
  shell = SimpleShell.new(build.root)
85
- shell.mv %W(build, #{build.commit})
85
+ shell.mv %W(build #{build.commit})
86
86
  tar = shell.tar %W(-cjf #{build.commit}.tar.bz2 #{build.commit})
87
87
  if tar.S?.to_i == 0
88
88
  shell.rm %W(-rf #{build.commit}/)
data/lib/heidi/hook.rb CHANGED
@@ -16,7 +16,10 @@ class Heidi
16
16
 
17
17
  env = {
18
18
  'HEIDI_LOG_DIR' => build.log_root,
19
- 'HEIDI_BUILD_DIR' => where
19
+ 'HEIDI_BUILD_DIR' => where,
20
+ 'RUBYOPT' => nil,
21
+ 'BUNDLE_BIN_PATH' => nil,
22
+ 'BUNDLE_GEMFILE' => nil,
20
23
  }
21
24
 
22
25
  shell = SimpleShell.new(where, env)
@@ -8,9 +8,10 @@ class Heidi
8
8
  attr_reader :build, :project
9
9
 
10
10
  def initialize(project)
11
- @project = project
12
- @build = Heidi::Build.new(project)
13
- @failed = false
11
+ @project = project
12
+ @build = Heidi::Build.new(project)
13
+ @failed = false
14
+ @hooks_ran = []
14
15
  end
15
16
 
16
17
  def failure
@@ -32,9 +33,11 @@ class Heidi
32
33
  end
33
34
 
34
35
  def integrate
35
- @start = Time.now
36
- build.lock
37
36
  build.load_hooks
37
+ return "no test hooks!" if build.hooks[:tests].empty?
38
+
39
+ build.lock
40
+ @start = Time.now
38
41
  build.clean
39
42
 
40
43
  return failure if !run_hooks(:before)
@@ -64,11 +67,10 @@ class Heidi
64
67
  # always unlock the build root, no matter what
65
68
  build.unlock
66
69
 
67
- return @failed == true ? false : true
68
-
69
70
  end
70
71
 
71
72
  def run_hooks(where)
73
+ return true if @hooks_ran.include?(where)
72
74
  return true if build.hooks[where].nil? || build.hooks[where].empty?
73
75
 
74
76
  hooks_failed = false
@@ -87,6 +89,8 @@ class Heidi
87
89
  end
88
90
  end
89
91
 
92
+ @hooks_ran << where
93
+
90
94
  return hooks_failed == true ? false : true
91
95
  end
92
96
 
data/lib/heidi/project.rb CHANGED
@@ -71,11 +71,19 @@ class Heidi
71
71
 
72
72
  def integrate
73
73
  return "locked" if locked?
74
+ return true if self.current_build == self.commit
75
+
76
+ status = "unknown"
74
77
 
75
- status = ""
76
78
  self.lock do
77
79
  res = Heidi::Integrator.new(self).integrate
78
- status = res != true ? "failed" : "passed"
80
+ if res == true
81
+ status = nil
82
+ elsif res.is_a? String
83
+ status = res
84
+ else
85
+ status = "failed"
86
+ end
79
87
  end
80
88
 
81
89
  return status
@@ -5,6 +5,11 @@
5
5
 
6
6
  <h2 class="<%= build.status %>"><%= build.commit %></h2>
7
7
 
8
+ <% if build.status == "passed" %>
9
+ <a href='/projects/<%= project.name %>/build/<%= build.commit %>/tar_ball'>download</a>
10
+ <br /><br />
11
+ <% end %>
12
+
8
13
  | <% build.logs.each do |log| %>
9
14
  <a href="#<%= log.file_name %>"><%= log.file_name %></a> |
10
15
  <% end %>
data/lib/heidi/web.rb CHANGED
@@ -27,10 +27,10 @@ class Heidi
27
27
  set :root, dir
28
28
 
29
29
  get '/' do
30
- redirect '/projects', 302
30
+ redirect '/projects/', 302
31
31
  end
32
32
 
33
- get '/projects' do
33
+ get '/projects/' do
34
34
  erb(:home, { :locals => { :projects => @heidi.projects }})
35
35
  end
36
36
 
@@ -54,6 +54,36 @@ class Heidi
54
54
  erb(:build, { :locals => { :build => build, :project => project }})
55
55
  end
56
56
 
57
+ get '/projects/:name/build/:commit/tar_ball' do
58
+ project = @heidi[params[:name]]
59
+ if project.nil?
60
+ return "no project by that name: #{params[:name]}"
61
+ end
62
+
63
+ # load build of project
64
+ build = Heidi::Build.new(project, params[:commit])
65
+
66
+ ball = build.tar_ball
67
+ if ball.nil?
68
+ return "no tar ball here..."
69
+ end
70
+
71
+ content_type 'application/x-tar'
72
+ headers "Content-type" => "application/x-tar",
73
+ "Content-disposition" => "attachment; filename=#{build.commit}.tar.bz2"
74
+
75
+ stream do |out|
76
+ while true
77
+ begin
78
+ out << ball.sysread(1024)
79
+ rescue EOFError
80
+ break
81
+ end
82
+ end
83
+ end
84
+
85
+ end
86
+
57
87
  put '/projects/:name/build' do
58
88
  project = $heidi[params[:name]]
59
89
  if project.nil?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heidi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thin
16
- requirement: &88342980 !ruby/object:Gem::Requirement
16
+ requirement: &74669360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *88342980
24
+ version_requirements: *74669360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sinatra
27
- requirement: &88342660 !ruby/object:Gem::Requirement
27
+ requirement: &74669010 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *88342660
35
+ version_requirements: *74669010
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: simple_shell
38
- requirement: &88342390 !ruby/object:Gem::Requirement
38
+ requirement: &74668670 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *88342390
46
+ version_requirements: *74668670
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &88342100 !ruby/object:Gem::Requirement
49
+ requirement: &74668320 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.8.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *88342100
57
+ version_requirements: *74668320
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rdoc
60
- requirement: &88336620 !ruby/object:Gem::Requirement
60
+ requirement: &74667940 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '3.12'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *88336620
68
+ version_requirements: *74667940
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
- requirement: &88336290 !ruby/object:Gem::Requirement
71
+ requirement: &74667560 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 1.0.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *88336290
79
+ version_requirements: *74667560
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: jeweler
82
- requirement: &88335980 !ruby/object:Gem::Requirement
82
+ requirement: &74667230 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.8.3
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *88335980
90
+ version_requirements: *74667230
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rcov
93
- requirement: &88335610 !ruby/object:Gem::Requirement
93
+ requirement: &74666910 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *88335610
101
+ version_requirements: *74666910
102
102
  description: CI-Joe alike CI system called Heidi.
103
103
  email: hartog@organisedminds.com
104
104
  executables:
@@ -164,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
164
  version: '0'
165
165
  segments:
166
166
  - 0
167
- hash: 976853793
167
+ hash: -666476931
168
168
  required_rubygems_version: !ruby/object:Gem::Requirement
169
169
  none: false
170
170
  requirements: