foca-integrity 0.1.9.1 → 0.1.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +12 -0
  2. data/CHANGES +28 -0
  3. data/README.markdown +6 -0
  4. data/Rakefile +44 -83
  5. data/config/heroku/.gems +0 -3
  6. data/config/heroku/integrity-config.rb +4 -1
  7. data/integrity.gemspec +18 -6
  8. data/lib/integrity.rb +9 -5
  9. data/lib/integrity/app.rb +8 -8
  10. data/lib/integrity/build.rb +14 -7
  11. data/lib/integrity/commit.rb +0 -8
  12. data/lib/integrity/helpers/authorization.rb +1 -1
  13. data/lib/integrity/helpers/breadcrumbs.rb +1 -1
  14. data/lib/integrity/helpers/rendering.rb +8 -2
  15. data/lib/integrity/helpers/urls.rb +33 -23
  16. data/lib/integrity/installer.rb +18 -17
  17. data/lib/integrity/notifier/base.rb +12 -3
  18. data/lib/integrity/project.rb +6 -6
  19. data/lib/integrity/project_builder.rb +35 -35
  20. data/test/acceptance/api_test.rb +1 -1
  21. data/test/acceptance/browse_project_builds_test.rb +1 -1
  22. data/test/acceptance/browse_project_test.rb +1 -1
  23. data/test/acceptance/build_notifications_test.rb +1 -1
  24. data/test/acceptance/create_project_test.rb +1 -1
  25. data/test/acceptance/delete_project_test.rb +1 -1
  26. data/test/acceptance/edit_project_test.rb +1 -1
  27. data/test/acceptance/error_page_test.rb +1 -1
  28. data/test/acceptance/installer_test.rb +2 -6
  29. data/test/acceptance/manual_build_project_test.rb +1 -1
  30. data/test/acceptance/not_found_page_test.rb +29 -0
  31. data/test/acceptance/notifier_test.rb +1 -1
  32. data/test/acceptance/project_syndication_test.rb +1 -1
  33. data/test/acceptance/stylesheet_test.rb +10 -2
  34. data/test/acceptance/unauthorized_page_test.rb +20 -0
  35. data/test/helpers.rb +20 -7
  36. data/test/helpers/acceptance.rb +1 -0
  37. data/test/unit/build_test.rb +33 -0
  38. data/test/unit/commit_test.rb +0 -21
  39. data/test/unit/helpers_test.rb +67 -20
  40. data/test/unit/integrity_test.rb +23 -6
  41. data/test/unit/migrations_test.rb +2 -2
  42. data/test/unit/notifier_test.rb +5 -0
  43. data/test/unit/project_builder_test.rb +8 -1
  44. data/test/unit/project_test.rb +7 -0
  45. data/views/home.haml +2 -2
  46. data/views/layout.haml +6 -5
  47. data/views/new.haml +1 -1
  48. data/views/not_found.haml +2 -2
  49. data/views/unauthorized.haml +4 -4
  50. metadata +105 -6
  51. data/test/acceptance/helpers.rb +0 -2
  52. data/vendor/sinatra-ditties/README.rdoc +0 -3
  53. data/vendor/sinatra-ditties/lib/sinatra/ditties.rb +0 -12
  54. data/vendor/sinatra-ditties/lib/sinatra/ditties/authorization.rb +0 -61
  55. data/vendor/sinatra-ditties/lib/sinatra/ditties/mailer.rb +0 -146
@@ -1,4 +1,4 @@
1
- require "sinatra/ditties"
1
+ require "sinatra/authorization"
2
2
 
3
3
  module Integrity
4
4
  module Helpers
@@ -2,7 +2,7 @@ module Integrity
2
2
  module Helpers
3
3
  module Breadcrumbs
4
4
  def pages
5
- @pages ||= [["projects", "/"], ["new project", "/new"]]
5
+ @pages ||= [["projects", root_path], ["new project", root_path("/new")]]
6
6
  end
7
7
 
8
8
  def breadcrumbs(*crumbs)
@@ -1,9 +1,15 @@
1
1
  module Integrity
2
2
  module Helpers
3
3
  module Rendering
4
+ def stylesheets(*sheets)
5
+ sheets.each { |sheet|
6
+ haml_tag(:link, :href => root_path("/#{sheet}.css"),
7
+ :type => "text/css", :rel => "stylesheet")
8
+ }
9
+ end
10
+
4
11
  def stylesheet_hash
5
- @_hash ||= Digest::MD5.file(
6
- options.views + "/integrity.sass").tap { |file| file.hexdigest }
12
+ @_hash ||= Digest::MD5.file(options.views + "/integrity.sass").hexdigest
7
13
  end
8
14
 
9
15
  def show(view, options={})
@@ -1,49 +1,59 @@
1
1
  module Integrity
2
2
  module Helpers
3
3
  module Urls
4
- def url(path)
5
- Addressable::URI.parse(request.url).join(path).to_s
6
- end
7
-
8
4
  def root_url
9
- url("/")
5
+ @url ||= Addressable::URI.parse(base_url)
10
6
  end
11
7
 
12
- def project_path(project, *path)
13
- "/" << [project.permalink, *path].join("/")
8
+ def root_path(path="")
9
+ url(path).path
14
10
  end
15
11
 
16
12
  def project_url(project, *path)
17
- url project_path(project, *path)
13
+ url("/" << [project.permalink, *path].flatten.join("/"))
18
14
  end
19
15
 
20
- def push_url_for(project)
21
- Addressable::URI.parse(project_url(project, "push")).tap do |url|
22
- if Integrity.config[:use_basic_auth]
23
- url.user = Integrity.config[:admin_username]
24
- url.password = Integrity.config[:hash_admin_password] ?
25
- "<password>" : Integrity.config[:admin_password]
26
- end
27
- end.to_s
16
+ def project_path(project, *path)
17
+ project_url(project, path).path
18
+ end
19
+
20
+ def commit_url(commit)
21
+ project_url(commit.project, "commits", commit.identifier)
28
22
  end
29
23
 
30
24
  def commit_path(commit, *path)
31
- project_path(commit.project, "commits", commit.identifier, *path)
25
+ commit_url(commit).path
32
26
  end
33
27
 
34
28
  def build_path(build, *path)
35
- warn "#build_path is deprecated, use #commit_path instead"
29
+ warn "#build_path is deprecated, use #commit_path instead (#{caller[0]})"
36
30
  commit_path build.commit, *path
37
31
  end
38
32
 
39
- def commit_url(commit)
40
- url commit_path(commit)
41
- end
42
-
43
33
  def build_url(build)
44
- warn "#build_url is deprecated, use #commit_url instead"
34
+ warn "#build_url is deprecated, use #commit_url instead (#{caller[0]})"
45
35
  commit_url build.commit
46
36
  end
37
+
38
+ def push_url_for(project)
39
+ Addressable::URI.parse(project_url(project, "push")).tap do |url|
40
+ if Integrity.config[:use_basic_auth]
41
+ url.user = Integrity.config[:admin_username]
42
+ url.password = Integrity.config[:hash_admin_password] ?
43
+ "<password>" : Integrity.config[:admin_password]
44
+ end
45
+ end.to_s
46
+ end
47
+
48
+ private
49
+ def url(path="")
50
+ root_url.dup.tap { |url| url.path = root_url.path + path }
51
+ end
52
+
53
+ def base_url
54
+ Integrity.config[:base_uri] || ((respond_to?(:request) &&
55
+ request.respond_to?(:url)) ? request.url : fail("set base_uri"))
56
+ end
47
57
  end
48
58
  end
49
59
  end
@@ -16,20 +16,13 @@ module Integrity
16
16
 
17
17
  if options[:heroku]
18
18
  cp_r Pathname(__FILE__).join("../../../config/heroku"), root
19
- puts <<EOF
20
- Your Integrity install is ready to be deployed onto Heroku. Next steps:
21
-
22
- 1. git init && git add . && git commit -am "Initial import"
23
- 2. heroku create
24
- 3. git push heroku master
25
- 4. heroku rake db:migrate
26
- EOF
19
+ puts post_heroku_install_message
27
20
  else
28
21
  create_dir_structure
29
22
  copy_template_files
30
23
  edit_template_files
31
24
  migrate_db(root.join("config.yml"))
32
- after_setup_message
25
+ puts post_install_message
33
26
  end
34
27
  end
35
28
 
@@ -50,11 +43,8 @@ EOF
50
43
  require "thin"
51
44
  require "do_sqlite3"
52
45
 
53
- if File.file?(options[:config].to_s)
54
- Integrity.new(options[:config])
55
- else
56
- DataMapper.setup(:default, "sqlite3::memory:")
57
- end
46
+ File.file?(options[:config].to_s) ?
47
+ Integrity.new(options[:config]) : Integrity.new
58
48
 
59
49
  DataMapper.auto_migrate!
60
50
 
@@ -104,8 +94,19 @@ EOF
104
94
  File.open(root / "thin.yml", 'w') { |f| f.puts config }
105
95
  end
106
96
 
107
- def after_setup_message
108
- puts <<EOF
97
+ def post_heroku_install_message
98
+ <<EOF
99
+ Your Integrity install is ready to be deployed onto Heroku. Next steps:
100
+
101
+ 1. git init && git add . && git commit -am "Initial import"
102
+ 2. heroku create
103
+ 3. git push heroku master
104
+ 4. heroku rake db:migrate
105
+ EOF
106
+ end
107
+
108
+ def post_install_message
109
+ <<EOF
109
110
  Awesome! Integrity was installed successfully!
110
111
 
111
112
  If you want to enable notifiers, install the gems and then require them
@@ -113,7 +114,7 @@ in #{root}/config.ru
113
114
 
114
115
  For example:
115
116
 
116
- sudo gem install -s http://gems.github.com foca-integrity-email)
117
+ sudo gem install -s http://gems.github.com foca-integrity-email
117
118
 
118
119
  And then in #{root}/config.ru add:
119
120
 
@@ -2,7 +2,11 @@ module Integrity
2
2
  class Notifier
3
3
  class Base
4
4
  def self.notify_of_build(build, config)
5
- Timeout.timeout(8) { new(build, config).deliver! }
5
+ Integrity.log "Notifying of build #{build.commit.short_identifier} using the #{self.class} notifier"
6
+ Timeout.timeout(8) { new(build.commit, config).deliver! }
7
+ rescue Timeout::Error
8
+ Integrity.log "#{notifier.name} notifier timed out"
9
+ false
6
10
  end
7
11
 
8
12
  def self.to_haml
@@ -17,7 +21,7 @@ module Integrity
17
21
  end
18
22
 
19
23
  def build
20
- warn "Notifier::Base#build is deprecated, use Notifier::Base#commit instead"
24
+ warn "Notifier::Base#build is deprecated, use Notifier::Base#commit instead (#{caller[0]})"
21
25
  commit
22
26
  end
23
27
 
@@ -50,6 +54,11 @@ EOM
50
54
  Integrity.config[:base_uri] / commit.project.permalink / "commits" / commit.identifier
51
55
  end
52
56
 
57
+ def build_url
58
+ warn "Notifier::Base#build_url is deprecated, use Notifier::Base#commit_url instead (#{caller[0]})"
59
+ commit_url
60
+ end
61
+
53
62
  private
54
63
 
55
64
  def stripped_commit_output
@@ -57,7 +66,7 @@ EOM
57
66
  end
58
67
 
59
68
  def stripped_build_output
60
- warn "Notifier::Base#stripped_build_output is deprecated, use Notifier::base#stripped_commit_output instead"
69
+ warn "Notifier::Base#stripped_build_output is deprecated, use Notifier::base#stripped_commit_output instead (#{caller[0]})"
61
70
  stripped_commit_output
62
71
  end
63
72
  end
@@ -17,7 +17,7 @@ module Integrity
17
17
  has n, :notifiers, :class_name => "Integrity::Notifier"
18
18
 
19
19
  before :save, :set_permalink
20
- before :destroy, :delete_code
20
+ before :destroy, :delete_working_directory
21
21
 
22
22
  validates_is_unique :name
23
23
 
@@ -32,7 +32,7 @@ module Integrity
32
32
  def build(commit_identifier="HEAD")
33
33
  commit_identifier = head_of_remote_repo if commit_identifier == "HEAD"
34
34
  commit = find_or_create_commit_with_identifier(commit_identifier)
35
- commit.queue_build
35
+ Build.queue(commit)
36
36
  end
37
37
 
38
38
  def push(payload)
@@ -57,7 +57,7 @@ module Integrity
57
57
  end
58
58
 
59
59
  def last_build
60
- warn "Project#last_build is deprecated, use Project#last_commit"
60
+ warn "Project#last_build is deprecated, use Project#last_commit (#{caller[0]})"
61
61
  last_commit
62
62
  end
63
63
 
@@ -66,7 +66,7 @@ module Integrity
66
66
  end
67
67
 
68
68
  def previous_builds
69
- warn "Project#previous_builds is deprecated, use Project#previous_commits"
69
+ warn "Project#previous_builds is deprecated, use Project#previous_commits (#{caller[0]})"
70
70
  previous_commits
71
71
  end
72
72
 
@@ -131,9 +131,9 @@ module Integrity
131
131
  gsub(/-*$/, "")
132
132
  end
133
133
 
134
- def delete_code
134
+ def delete_working_directory
135
135
  commits.all(:project_id => id).destroy!
136
- ProjectBuilder.new(self).delete_code
136
+ ProjectBuilder.delete_working_directory(self)
137
137
  rescue SCM::SCMUnknownError => error
138
138
  Integrity.log "Problem while trying to deleting code: #{error}"
139
139
  end
@@ -1,24 +1,45 @@
1
+ require "forwardable"
2
+
1
3
  module Integrity
2
4
  class ProjectBuilder
5
+ extend Forwardable
6
+
7
+ attr_accessor :project, :scm
8
+ def_delegators :project, :name, :uri, :command, :branch
9
+
10
+ def self.build(commit)
11
+ new(commit.project).build(commit)
12
+ end
13
+
14
+ def self.delete_working_directory(project)
15
+ new(project).delete_code
16
+ end
17
+
3
18
  def initialize(project)
4
19
  @project = project
5
- @uri = project.uri
6
- @build_script = project.command
7
- @branch = project.branch
8
- @scm = SCM.new(@uri, @branch, export_directory)
20
+ @scm = SCM.new(uri, branch, export_directory)
9
21
  end
10
22
 
11
23
  def build(commit)
12
- @commit = commit
13
- @build = commit.build
14
- @build.start!
15
- Integrity.log "Building #{commit.identifier} (#{@branch}) of #{@project.name} in #{export_directory} using #{@scm.name}"
16
- @scm.with_revision(commit.identifier) { run_build_script }
17
- @build
24
+ build = commit.build
25
+ build.start!
26
+
27
+ Integrity.log "Building #{commit.identifier} (#{branch}) of #{name} in" +
28
+ "#{export_directory} using #{scm.name}"
29
+
30
+ scm.with_revision(commit.identifier) do
31
+ Integrity.log "Running `#{command}` in #{scm.working_directory}"
32
+
33
+ IO.popen("(cd #{scm.working_directory} && #{command}) 2>&1", "r") {
34
+ |output| build.output = output.read }
35
+ build.successful = $?.success?
36
+ end
37
+
38
+ build
18
39
  ensure
19
- @build.complete!
20
- @commit.update_attributes(@scm.info(commit.identifier))
21
- send_notifications
40
+ build.complete!
41
+ commit.update_attributes(scm.info(commit.identifier) || {})
42
+ project.notifiers.each { |notifier| notifier.notify_of_build(build) }
22
43
  end
23
44
 
24
45
  def delete_code
@@ -28,29 +49,8 @@ module Integrity
28
49
  end
29
50
 
30
51
  private
31
- def send_notifications
32
- @project.notifiers.each do |notifier|
33
- begin
34
- Integrity.log "Notifying of build #{@commit.short_identifier} using the #{notifier.name} notifier"
35
- notifier.notify_of_build @commit
36
- rescue Timeout::Error
37
- Integrity.log "#{notifier.name} notifier timed out"
38
- next
39
- end
40
- end
41
- end
42
-
43
52
  def export_directory
44
- Integrity.config[:export_directory] / "#{SCM.working_tree_path(@uri)}-#{@branch}"
45
- end
46
-
47
- def run_build_script
48
- Integrity.log "Running `#{@build_script}` in #{@scm.working_directory}"
49
-
50
- IO.popen "(cd #{@scm.working_directory} && #{@build_script}) 2>&1", "r" do |pipe|
51
- @build.output = pipe.read
52
- end
53
- @build.successful = $?.success?
53
+ Integrity.config[:export_directory] / "#{SCM.working_tree_path(uri)}-#{branch}"
54
54
  end
55
55
  end
56
56
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class ApiTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOF
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class BrowseProjectBuildsTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class BrowsePublicProjectsTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
  require "helpers/acceptance/textfile_notifier"
3
3
 
4
4
  class BuildNotificationsTest < Test::Unit::AcceptanceTestCase
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class CreateProjectTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class DeleteProjectTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class EditProjectTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class ErrorPageTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
  require "integrity/installer"
3
3
 
4
4
  class InstallerTest < Test::Unit::AcceptanceTestCase
@@ -65,11 +65,7 @@ class InstallerTest < Test::Unit::AcceptanceTestCase
65
65
  scenario "Installing Integrity for Heroku" do
66
66
  message = install("--heroku")
67
67
 
68
- gemifest = root.join(".gems").read
69
- assert gemifest.include?("mailfactory")
70
- assert gemifest.include?("tlsmail")
71
- assert gemifest.include?("foca-sinatra-ditties")
72
- assert gemifest.include?("integrity")
68
+ assert_equal "integrity --version 0.1.9.0", root.join(".gems").read.chomp
73
69
 
74
70
  assert root.join("Rakefile").file?
75
71
  assert root.join("integrity-config.rb").file?
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/helpers"
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
2
 
3
3
  class ManualBuildProjectTest < Test::Unit::AcceptanceTestCase
4
4
  story <<-EOS
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + "/../helpers/acceptance"
2
+
3
+ class NotFoundPageTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As an visitor,
6
+ I want to be shown a friendly four oh four
7
+ So that I DON'T HAVE TO THINK.
8
+ EOS
9
+
10
+ scenario "chilling on some Integrity instance found via The Holy Hub" do
11
+ project = Project.gen
12
+
13
+ visit "/42"
14
+ assert_equal 404, response_code
15
+
16
+ click_link "list of projects"
17
+ assert_contain(project.name)
18
+
19
+ visit "/42"
20
+
21
+ click_link "the projects list"
22
+ assert_contain(project.name)
23
+
24
+ visit "/42"
25
+
26
+ click_link "back from whence you came"
27
+ assert_contain("Add a new project")
28
+ end
29
+ end