polisher 0.1 → 0.2

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 (103) hide show
  1. data/COPYING +8 -0
  2. data/LICENSE +661 -0
  3. data/README.rdoc +25 -0
  4. data/Rakefile +92 -0
  5. data/TODO +6 -0
  6. data/bin/server +3 -0
  7. data/config/database.yml +8 -43
  8. data/config/polisher.yml +15 -5
  9. data/config.ru +25 -0
  10. data/db/connection.rb +49 -0
  11. data/db/migrations/001_create_sources.rb +27 -0
  12. data/db/migrations/002_create_managed_gems.rb +24 -0
  13. data/db/migrations/003_create_events.rb +27 -0
  14. data/db/models/event.rb +61 -0
  15. data/db/models/managed_gem.rb +111 -0
  16. data/db/models/source.rb +35 -0
  17. data/lib/common.rb +39 -0
  18. data/lib/event_handlers.rb +100 -0
  19. data/lib/sinatra/url_for.rb +40 -0
  20. data/polisher.rb +120 -0
  21. data/public/javascripts/polisher.js +15 -0
  22. data/public/stylesheets/style.css +18 -3
  23. data/spec/event_handlers_spec.rb +164 -0
  24. data/spec/models_spec.rb +193 -0
  25. data/spec/polisher_spec.rb +133 -0
  26. data/spec/spec_helper.rb +44 -0
  27. data/views/gems/index.haml +106 -0
  28. data/views/layout.haml +24 -0
  29. data/views/sources/index.haml +41 -0
  30. metadata +36 -93
  31. data/README +0 -243
  32. data/app/controllers/application_controller.rb +0 -12
  33. data/app/controllers/callback_controller.rb +0 -47
  34. data/app/controllers/manage_controller.rb +0 -112
  35. data/app/helpers/application_helper.rb +0 -3
  36. data/app/models/artifact.rb +0 -21
  37. data/app/models/event_handler.rb +0 -61
  38. data/app/models/gem_search_criteria.rb +0 -24
  39. data/app/models/gem_source.rb +0 -43
  40. data/app/models/managed_gem.rb +0 -47
  41. data/app/views/callback/gem_updated.rhtml +0 -0
  42. data/app/views/layouts/_header.rhtml +0 -8
  43. data/app/views/layouts/index.rhtml +0 -27
  44. data/app/views/manage/create_event_handler.rhtml +0 -15
  45. data/app/views/manage/create_gem.rhtml +0 -15
  46. data/app/views/manage/create_gem_source.rhtml +0 -15
  47. data/app/views/manage/delete_event_handler.rhtml +0 -15
  48. data/app/views/manage/delete_gem.rhtml +0 -15
  49. data/app/views/manage/delete_gem_source.rhtml +0 -15
  50. data/app/views/manage/list.rhtml +0 -66
  51. data/app/views/manage/new_event_handler.rhtml +0 -38
  52. data/app/views/manage/new_gem.rhtml +0 -21
  53. data/app/views/manage/new_gem_search_criteria.rhtml +0 -3
  54. data/app/views/manage/new_gem_source.rhtml +0 -10
  55. data/config/boot.rb +0 -110
  56. data/config/environment.rb +0 -44
  57. data/config/environments/development.rb +0 -17
  58. data/config/environments/production.rb +0 -28
  59. data/config/environments/test.rb +0 -28
  60. data/config/initializers/backtrace_silencers.rb +0 -7
  61. data/config/initializers/inflections.rb +0 -10
  62. data/config/initializers/mime_types.rb +0 -5
  63. data/config/initializers/new_rails_defaults.rb +0 -21
  64. data/config/initializers/session_store.rb +0 -15
  65. data/config/locales/en.yml +0 -5
  66. data/config/routes.rb +0 -44
  67. data/db/migrate/001_create_gem_sources.rb +0 -34
  68. data/db/migrate/002_create_managed_gems.rb +0 -32
  69. data/db/migrate/003_create_gem_search_criterias.rb +0 -33
  70. data/db/migrate/004_create_event_handlers.rb +0 -32
  71. data/db/migrate/005_create_artifacts.rb +0 -32
  72. data/db/schema.rb +0 -42
  73. data/db/seeds.rb +0 -7
  74. data/lib/email_adapter.rb +0 -46
  75. data/lib/gem2rpm.rb +0 -189
  76. data/lib/gem_api_adapter.rb +0 -87
  77. data/lib/rpm_adapter.rb +0 -39
  78. data/public/404.html +0 -30
  79. data/public/422.html +0 -30
  80. data/public/500.html +0 -30
  81. data/public/dispatch.cgi +0 -10
  82. data/public/dispatch.fcgi +0 -24
  83. data/public/dispatch.rb +0 -29
  84. data/public/favicon.ico +0 -0
  85. data/public/images/rails.png +0 -0
  86. data/public/javascripts/application.js +0 -2
  87. data/public/javascripts/controls.js +0 -963
  88. data/public/javascripts/dragdrop.js +0 -973
  89. data/public/javascripts/effects.js +0 -1128
  90. data/public/javascripts/prototype.js +0 -4320
  91. data/public/robots.txt +0 -5
  92. data/script/about +0 -4
  93. data/script/console +0 -3
  94. data/script/dbconsole +0 -3
  95. data/script/destroy +0 -3
  96. data/script/generate +0 -3
  97. data/script/performance/benchmarker +0 -3
  98. data/script/performance/profiler +0 -3
  99. data/script/plugin +0 -3
  100. data/script/runner +0 -3
  101. data/script/server +0 -3
  102. data/tmp/gems/README +0 -1
  103. data/tmp/rpms/README +0 -1
data/README.rdoc ADDED
@@ -0,0 +1,25 @@
1
+ == Rubygem Polisher
2
+ Copyright (C) 2010 Red Hat, Inc.
3
+ Written by Mohammed Morsi <mmorsi@redhat.com>
4
+
5
+ === Intro
6
+ Polisher is a post-publishing processing webapp for rubygems. It allows for
7
+ the configuration of events to be run on target gem/version updates. Polisher
8
+ makes uses of the gemcutter webhook API in conjunction with the sinatra/rack
9
+ web framework to subscribe to gem updates to run any specified/arbitrary event
10
+ handler callbacks.
11
+
12
+ === Running
13
+ Simply 'gem install polisher'
14
+
15
+ Also checkout the source from github via
16
+
17
+ 'git clone git://github.com/movitto/polisher.git'
18
+
19
+ To run the spec suite simply run
20
+
21
+ 'rake spec'
22
+
23
+
24
+ === Using
25
+ See the generated API and specs
data/Rakefile ADDED
@@ -0,0 +1,92 @@
1
+ # polisher project Rakefile
2
+
3
+ require 'lib/common'
4
+ require 'db/connection'
5
+ require 'rake/rdoctask'
6
+ require 'spec/rake/spectask'
7
+ require 'rake/gempackagetask'
8
+
9
+ #task :default => :test
10
+
11
+ env = ENV['RACK_ENV']
12
+ env ||= 'development'
13
+
14
+ logger = Logger.new(STDOUT)
15
+
16
+ GEM_NAME='polisher'
17
+ PKG_VERSION='0.2'
18
+
19
+ namespace :db do
20
+ task :migrate do
21
+ desc "Migrate the database"
22
+ Polisher::DB.connect Polisher::DB.load_config('./config/database.yml', env), logger
23
+ Polisher::DB.migrate './db/migrations'
24
+ end
25
+
26
+ task :rollback do
27
+ desc "Rollback the database"
28
+ Polisher::DB.connect Polisher::DB.load_config('./config/database.yml', env), logger
29
+ Polisher::DB.rollback './db/migrations'
30
+ end
31
+
32
+ task :drop_tables do
33
+ desc "Drop all tables in the database"
34
+ Polisher::DB.connect Polisher::DB.load_config('./config/database.yml', env), logger
35
+ Polisher::DB.drop_tables './db/migrations'
36
+ end
37
+ end
38
+
39
+ task 'test_env' do
40
+ env = 'test'
41
+ create_missing_polisher_dirs(:artifacts_dir => 'spec/artifacts', :db_data_dir => 'db/data', :log_dir => 'log')
42
+ end
43
+
44
+ desc "Run all specs"
45
+ Spec::Rake::SpecTask.new('spec' => ['test_env', 'db:drop_tables', 'db:migrate']) do |t|
46
+ t.spec_files = FileList['spec/*_spec.rb']
47
+ end
48
+
49
+ task :rdoc do
50
+ desc "Create RDoc documentation"
51
+ system "rdoc --title 'Polisher documentation' lib/"
52
+ end
53
+
54
+ Rake::RDocTask.new do |rd|
55
+ rd.main = "README.rdoc"
56
+ rd.rdoc_dir = "doc/site/api"
57
+ rd.rdoc_files.include("README.rdoc", "polisher.rb", "db/**/*.rb", "lib/**/*.rb")
58
+ end
59
+
60
+ task :create_gem do
61
+ desc "Create a new gem"
62
+ system "gem build polisher.gemspec"
63
+ end
64
+
65
+ PKG_FILES = FileList['bin/*', 'config/*.yml', 'config.ru', 'COPYING',
66
+ 'db/**/*.rb', 'lib/**/*.rb', 'LICENSE', 'polisher.rb', 'public/**/*', 'Rakefile',
67
+ 'README.rdoc', 'spec/**/*.rb', 'TODO', 'views/**/*.haml']
68
+
69
+ DIST_FILES = FileList[
70
+ "pkg/*.tgz", "pkg/*.gem"
71
+ ]
72
+
73
+ SPEC = Gem::Specification.new do |s|
74
+ s.name = GEM_NAME
75
+ s.version = PKG_VERSION
76
+ s.files = PKG_FILES
77
+
78
+ s.required_ruby_version = '>= 1.8.1'
79
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.3")
80
+
81
+ s.author = "Mohammed Morsi"
82
+ s.email = "mmorsi@redhat.com"
83
+ s.date = %q{2010-01-13}
84
+ s.description = "Ruby gem polisher"
85
+ s.summary = "Ruby gem polisher"
86
+ s.homepage = "http://github.com/movitto/polisher"
87
+ end
88
+
89
+ Rake::GemPackageTask.new(SPEC) do |pkg|
90
+ pkg.need_tar = true
91
+ pkg.need_zip = true
92
+ end
data/TODO ADDED
@@ -0,0 +1,6 @@
1
+ - Remaining TODO's, FIXME's, etc
2
+ - Syncronization locks needed! (on all shared artifacts, db objects)
3
+ - More event handlers, generic handler interface,
4
+ workflow integration to automatically chain handlers together
5
+ - multiple user support, RBAC and ACL mechanisms
6
+ - simple command line utility / api interface
data/bin/server ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ rake db:migrate
3
+ thin start --debug -R config.ru
data/config/database.yml CHANGED
@@ -1,48 +1,13 @@
1
- # PostgresSQL. Versions 8.2 recommended.
2
- #
3
- # Fedora Install Instructions:
4
- # sudo yum install ruby-postgres postgresql-server
5
- # sudo /sbin/service postgresql initdb
6
- # sudo /sbin/service postgresql start
7
- # sudo su - postgres
8
- # $ createdb polisher
9
- # $ psql polisher
10
- # $-# CREATE USER polisher WITH PASSWORD 'polisher';
11
- # $-# CREATE DATABASE polisher_development;
12
- # $-# GRANT ALL PRIVILEGES ON DATABASE polisher_development to polisher;
13
- # $-# CREATE DATABASE polisher_test;
14
- # $-# GRANT ALL PRIVILEGES ON DATABASE polisher_test to polisher;
15
- # $-# CREATE DATABASE polisher;
16
- # $-# GRANT ALL PRIVILEGES ON DATABASE polisher to polisher;
17
- # $-# \q
18
- # $ exit
19
- # rake db:migrate
20
- #
21
- # On a local system you may need to edit this file to have only the following
22
- # /var/lib/pgsql/data/pg_hba.conf
23
- # local all all trust
24
- # host all all 127.0.0.1 255.255.255.255 trust
1
+ # polisher database configuration
25
2
 
3
+ production:
4
+ adapter: sqlite3
5
+ database: db/data/polisher.sqlite
26
6
 
27
7
  development:
28
- adapter: postgresql
29
- database: polisher
30
- username: polisher
31
- password: polisher
32
- host: localhost
8
+ adapter: sqlite3
9
+ database: db/data/polisher-development.sqlite
33
10
 
34
- # Warning: The database defined as 'test' will be erased and
35
- # re-generated from your development database when you run 'rake'.
36
- # Do not set this db to the same as development or production.
37
11
  test:
38
- adapter: postgresql
39
- database: polisher
40
- username: polisher
41
- host: localhost
42
-
43
- production:
44
- adapter: postgresql
45
- database: polisher
46
- username: polisher
47
- password: polisher
48
- host: localhost
12
+ adapter: sqlite3
13
+ database: db/data/polisher-test.sqlite
data/config/polisher.yml CHANGED
@@ -1,10 +1,20 @@
1
1
  development:
2
- gem_api_key: "YOUR_GEMCUTTER_KEY_HERE"
3
- smtp_server: "localhost"
4
- email_from: "user@host.com"
5
- email_to: "user@host.com"
6
- bugzilla_post_url: "https://bugzilla.redhat.com/post_bug.cgi"
2
+ gem_api_key: "YOUR GEMCUTTER API KEY HERE"
3
+ email_from: "foo@example.host"
4
+ email_server: "localhost"
5
+ email_subject: "gem #{gem_name} updated"
6
+ email_body: "gem #{gem_name} updated"
7
7
 
8
8
  test:
9
+ gem_api_key: "YOUR GEMCUTTER API KEY HERE"
10
+ email_from: "foo@example.host"
11
+ email_server: "localhost"
12
+ email_subject: "gem #{gem_name} updated"
13
+ email_body: "gem #{gem_name} updated"
9
14
 
10
15
  production:
16
+ gem_api_key: "YOUR GEMCUTTER API KEY HERE"
17
+ email_from: "foo@example.host"
18
+ email_server: "localhost"
19
+ email_subject: "gem #{gem_name} updated"
20
+ email_body: "gem #{gem_name} updated"
data/config.ru ADDED
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+
4
+ dir = File.dirname(__FILE__)
5
+
6
+ set :artifacts_dir => dir + '/artifacts'
7
+ set :polisher_config => dir + '/config/polisher.yml'
8
+ set :db_config => dir + '/config/database.yml'
9
+ set :db_data_dir => dir + '/db/data'
10
+ set :log_dir => dir + '/log/'
11
+ set :environment => :development
12
+ set :run => false
13
+ set :logging, true
14
+
15
+ #log = File.new(dir + "/log/sinatra.log", "a+")
16
+ #$stdout.reopen(log)
17
+ #$stderr.reopen(log)
18
+
19
+ set :raise_errors => true
20
+ use Rack::ShowExceptions
21
+
22
+ $: << "lib/"
23
+
24
+ require 'polisher.rb'
25
+ run Sinatra::Application
data/db/connection.rb ADDED
@@ -0,0 +1,49 @@
1
+ # ruby gem polisher common routines
2
+ #
3
+ # Copyright (C) 2010 Red Hat, Inc.
4
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
5
+ #
6
+ # This program is free software, you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation, either version 3
9
+ # of the License, or (at your option) any later version.
10
+ #
11
+ # You should have received a copy of the the GNU Affero
12
+ # General Public License, along with Polisher. If not, see
13
+ # <http://www.gnu.org/licenses/>
14
+
15
+ require 'active_record'
16
+
17
+ Dir[File.dirname(__FILE__) + '/models/*.rb'].each { |model| require model }
18
+
19
+ module Polisher
20
+ module DB
21
+
22
+ def self.load_config(file_path, env = 'development')
23
+ YAML::load(File.open(file_path))[env.to_s]
24
+ end
25
+
26
+ def self.connect(config, logger)
27
+ ActiveRecord::Base.logger = logger
28
+ ActiveRecord::Base.establish_connection config
29
+ end
30
+
31
+ def self.migrate(migrations_dir)
32
+ ActiveRecord::Migration.verbose = true
33
+ ActiveRecord::Migrator.migrate(migrations_dir)
34
+ end
35
+
36
+ # perform a single polisher db rollback
37
+ def self.rollback(migrations_dir)
38
+ ActiveRecord::Migration.verbose = true
39
+ ActiveRecord::Migrator.rollback(migrations_dir)
40
+ end
41
+
42
+ # drop all tables in the db
43
+ def self.drop_tables(migrations_dir)
44
+ ActiveRecord::Migration.verbose = true
45
+ ActiveRecord::Migrator.down(migrations_dir, 0)
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ class CreateSources < ActiveRecord::Migration
14
+ def self.up
15
+ create_table :sources do |t|
16
+ t.string :name
17
+ t.string :uri
18
+ end
19
+
20
+ # create entry for the official gemcutter repo
21
+ Source.create :name => "gemcutter", :uri => "http://gemcutter.org"
22
+ end
23
+
24
+ def self.down
25
+ drop_table :sources
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ class CreateManagedGems < ActiveRecord::Migration
14
+ def self.up
15
+ create_table :managed_gems do |t|
16
+ t.string :name
17
+ t.references :source
18
+ end
19
+ end
20
+
21
+ def self.down
22
+ drop_table :managed_gems
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ class CreateEvents < ActiveRecord::Migration
14
+ def self.up
15
+ create_table :events do |t|
16
+ t.references :managed_gem
17
+ t.string :process
18
+ t.string :gem_version
19
+ t.string :version_qualifier
20
+ t.string :process_options
21
+ end
22
+ end
23
+
24
+ def self.down
25
+ drop_table :events
26
+ end
27
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ class Event < ActiveRecord::Base
14
+ belongs_to :managed_gem
15
+ alias :gem :managed_gem
16
+
17
+ validates_presence_of :managed_gem_id, :process
18
+
19
+ # TODO right mow just returning a fixed list, at some point dynamically generate
20
+ def self.processes
21
+ ["create_package", "update_repo", "run_test_suite", "notify_subscribers"]
22
+ end
23
+
24
+ # version qualifiers
25
+ VERSION_QUALIFIERS = ['', '=', '>', '<', '>=', '<=']
26
+
27
+ validates_inclusion_of :version_qualifier, :in => VERSION_QUALIFIERS,
28
+ :if => Proc.new { |e| !e.version_qualifier.nil? }
29
+
30
+ validates_presence_of :gem_version,
31
+ :if => Proc.new { |e| !e.version_qualifier.nil? }
32
+
33
+ validates_presence_of :version_qualifier,
34
+ :if => Proc.new { |e| !e.gem_version.nil? }
35
+
36
+ # determine if event applies to specified version
37
+ def applies_to_version?(version)
38
+ gv, ev = version.to_f, gem_version.to_f
39
+ return (["", nil].include? version_qualifier ) ||
40
+ (version_qualifier == "=" && gv == ev) ||
41
+ (version_qualifier == ">" && gv > ev) ||
42
+ (version_qualifier == "<" && gv < ev) ||
43
+ (version_qualifier == ">=" && gv >= ev) ||
44
+ (version_qualifier == "<=" && gv <= ev)
45
+ end
46
+
47
+ # run the event
48
+ def run
49
+ # covert process to method name
50
+ handler = method(process.intern)
51
+
52
+ # generate array of params from semi-colon seperated options
53
+ params = process_options.nil? ? [] : process_options.split(';')
54
+
55
+ # first param is always the gem
56
+ params.unshift gem
57
+
58
+ # invoke
59
+ handler.call *params
60
+ end
61
+ end
@@ -0,0 +1,111 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ require 'uri'
14
+ require 'json'
15
+ require 'net/http'
16
+
17
+ # Gem representation in polisher, associated w/ rubygem being
18
+ # managed, used to track updates and invoke handlers
19
+ class ManagedGem < ActiveRecord::Base
20
+ belongs_to :source
21
+ has_many :events
22
+
23
+ validates_presence_of :name, :source_id
24
+ validates_uniqueness_of :name, :scope => :source_id
25
+
26
+ # TODO add validation to verify gem can be found in the associated gem source
27
+
28
+ # helper, extract source uri from specified gem uri
29
+ def self.uri_to_source_uri(gem_uri)
30
+ uri = URI.parse(gem_uri)
31
+ return uri.scheme + "://" + uri.host
32
+ end
33
+
34
+ # subscribe to updates to this gem from the associated gem source
35
+ def subscribe(args = {})
36
+ callback_url = args[:callback_url]
37
+ api_key = POLISHER_CONFIG["gem_api_key"]
38
+
39
+ subscribe_path = '/api/v1/web_hooks'
40
+ headers = { 'Authorization' => api_key }
41
+ data = "gem_name=#{name}&url=#{callback_url}"
42
+
43
+ http = Net::HTTP.new(URI.parse(source.uri).host, 80)
44
+ res = http.post(subscribe_path, data, headers)
45
+ # TODO handle res = #<Net::HTTPNotFound:0x7f1df8319e40> This gem could not be found
46
+ end
47
+
48
+ # determine if we are subscribed to gem
49
+ def subscribed?
50
+ api_key = POLISHER_CONFIG["gem_api_key"]
51
+
52
+ subscribe_path = '/api/v1/web_hooks.json'
53
+ headers = { 'Authorization' => api_key }
54
+
55
+ http = Net::HTTP.new(URI.parse(source.uri).host, 80)
56
+ res = http.get(subscribe_path, headers).body
57
+ res = JSON.parse(res)
58
+ return res.has_key?(name)
59
+ end
60
+
61
+ # unsubscribe to updates to this gem from associated gem source
62
+ def unsubscribe(args = {})
63
+ return unless subscribed?
64
+ callback_url = args[:callback_url]
65
+ api_key = POLISHER_CONFIG["gem_api_key"]
66
+
67
+ subscribe_path = "/api/v1/web_hooks/remove?gem_name=#{name}&url=#{callback_url}"
68
+ headers = { 'Authorization' => api_key }
69
+
70
+ http = Net::HTTP.new(URI.parse(source.uri).host, 80)
71
+ res = http.delete(subscribe_path, headers)
72
+ end
73
+
74
+ # return hash of gem attributes/values retreived from remote source
75
+ def get_info
76
+ info = nil
77
+ source_uri = URI.parse(source.uri).host
78
+ get_path = "/api/v1/gems/#{name}.json"
79
+ Net::HTTP.start(source_uri, 80) { |http|
80
+ info = JSON.parse(http.get(get_path).body)
81
+ }
82
+ return info
83
+ end
84
+
85
+ def download_to(args = {})
86
+ path = args.has_key?(:path) ? args[:path] : nil
87
+ dir = args.has_key?(:dir) ? args[:dir] : nil
88
+ version = args.has_key?(:version) ? args[:version] : nil
89
+
90
+ info = get_info
91
+ gem_uri = info["gem_uri"]
92
+ version = info["version"] if version.nil?
93
+ path = dir + "/#{name}-#{version}.gem" if path.nil?
94
+
95
+ # handle redirects
96
+ found = false
97
+ until found # TODO should impose a max tries
98
+ uri = URI.parse(gem_uri)
99
+ http = Net::HTTP.new(uri.host, 80)
100
+ res = http.get(uri.path)
101
+ if res.code == "200"
102
+ File.write path, res.body
103
+ found = true
104
+ else
105
+ gem_uri = res.header['location']
106
+ end
107
+ end
108
+
109
+ return path
110
+ end
111
+ end
@@ -0,0 +1,35 @@
1
+ # Copyright (C) 2010 Red Hat, Inc.
2
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
3
+ #
4
+ # This program is free software, you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License
6
+ # as published by the Free Software Foundation, either version 3
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # You should have received a copy of the the GNU Affero
10
+ # General Public License, along with Polisher. If not, see
11
+ # <http://www.gnu.org/licenses/>
12
+
13
+ # Source represents a remote endpoint which we will use
14
+ # the gem API to get gems / subscribe to updates
15
+ class Source < ActiveRecord::Base
16
+ has_many :managed_gems
17
+
18
+ alias :gems :managed_gems
19
+
20
+ validates_presence_of :name
21
+ validates_presence_of :uri
22
+ validates_uniqueness_of :name
23
+ validates_uniqueness_of :uri
24
+
25
+ # TODO validate format of uri
26
+
27
+ # TODO should have additional validation method that contacts gem source uri and
28
+ # makes sure it satisfiest gem API requests
29
+
30
+ # remove trailing slash in uri if present
31
+ before_save :clean_uri!
32
+ def clean_uri!
33
+ self.uri = self.uri[0...self.uri.size-1] if self.uri[-1].chr == '/'
34
+ end
35
+ end
data/lib/common.rb ADDED
@@ -0,0 +1,39 @@
1
+ # ruby gem polisher common routines
2
+ #
3
+ # Copyright (C) 2010 Red Hat, Inc.
4
+ # Written by Mohammed Morsi <mmorsi@redhat.com>
5
+ #
6
+ # This program is free software, you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation, either version 3
9
+ # of the License, or (at your option) any later version.
10
+ #
11
+ # You should have received a copy of the the GNU Affero
12
+ # General Public License, along with Polisher. If not, see
13
+ # <http://www.gnu.org/licenses/>
14
+
15
+ # read entire file into string
16
+ def File.read_all(path)
17
+ File.open(path, 'rb') {|file| return file.read }
18
+ end
19
+
20
+ # write contents of file from string
21
+ def File.write(path, str)
22
+ File.open(path, 'wb') {|file| file.write str }
23
+ end
24
+
25
+ # create any missing directories
26
+ def create_missing_polisher_dirs(args = {})
27
+ artifacts_dir = args[:artifacts_dir]
28
+ db_data_dir = args[:db_data_dir]
29
+ log_dir = args[:log_dir]
30
+
31
+ [artifacts_dir + '/gems',
32
+ artifacts_dir + '/repos',
33
+ artifacts_dir + '/SOURCES',
34
+ artifacts_dir + '/SPECS',
35
+ artifacts_dir + '/templates',
36
+ log_dir, db_data_dir].each { |dir|
37
+ FileUtils.mkdir_p(dir) unless File.directory? dir
38
+ }
39
+ end