polisher 0.4 → 0.5.1

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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -661
  3. data/README.md +39 -0
  4. data/Rakefile +11 -88
  5. data/bin/binary_gem_resolver.rb +95 -0
  6. data/bin/gem_dependency_checker.rb +165 -0
  7. data/bin/git_gem_updater.rb +86 -0
  8. data/bin/ruby_rpm_spec_updater.rb +29 -0
  9. data/lib/polisher.rb +19 -0
  10. data/lib/polisher/apt.rb +12 -0
  11. data/lib/polisher/bodhi.rb +21 -0
  12. data/lib/polisher/bugzilla.rb +9 -0
  13. data/lib/polisher/core.rb +33 -0
  14. data/lib/polisher/errata.rb +43 -0
  15. data/lib/polisher/fedora.rb +43 -0
  16. data/lib/polisher/gem.rb +155 -0
  17. data/lib/polisher/gemfile.rb +72 -0
  18. data/lib/polisher/gemspec.rb +32 -0
  19. data/lib/polisher/git.rb +135 -0
  20. data/lib/polisher/koji.rb +54 -0
  21. data/lib/polisher/rhn.rb +14 -0
  22. data/lib/polisher/rpmspec.rb +254 -0
  23. data/lib/polisher/upstream.rb +29 -0
  24. data/lib/polisher/vendor.rb +9 -0
  25. data/lib/polisher/version_checker.rb +100 -0
  26. data/lib/polisher/yum.rb +28 -0
  27. data/spec/core_spec.rb +64 -0
  28. data/spec/fedora_spec.rb +14 -0
  29. data/spec/gem_spec.rb +82 -0
  30. data/spec/gemfile_spec.rb +45 -0
  31. data/spec/git_spec.rb +74 -0
  32. data/spec/rpmspec_spec.rb +105 -0
  33. data/spec/spec_helper.rb +50 -37
  34. data/spec/upstream_spec.rb +39 -0
  35. metadata +173 -179
  36. data/COPYING +0 -8
  37. data/README.rdoc +0 -105
  38. data/TODO +0 -7
  39. data/bin/server +0 -4
  40. data/config.ru +0 -25
  41. data/config/database.yml +0 -13
  42. data/config/polisher.yml +0 -5
  43. data/db/connection.rb +0 -52
  44. data/db/migrations/001_create_projects.rb +0 -23
  45. data/db/migrations/002_create_sources.rb +0 -25
  46. data/db/migrations/003_create_project_source_versions.rb +0 -28
  47. data/db/migrations/004_create_events.rb +0 -27
  48. data/db/migrations/005_create_project_dependencies.rb +0 -28
  49. data/db/models/event.rb +0 -87
  50. data/db/models/project.rb +0 -110
  51. data/db/models/project_dependency.rb +0 -27
  52. data/db/models/project_source_version.rb +0 -31
  53. data/db/models/source.rb +0 -101
  54. data/lib/common.rb +0 -71
  55. data/lib/dsl.rb +0 -292
  56. data/lib/event_handlers.rb +0 -166
  57. data/lib/gem_adapter.rb +0 -94
  58. data/lib/sinatra/url_for.rb +0 -40
  59. data/polisher.rb +0 -372
  60. data/public/stylesheets/style.css +0 -67
  61. data/spec/common_spec.rb +0 -28
  62. data/spec/dsl_spec.rb +0 -357
  63. data/spec/event_handlers_spec.rb +0 -300
  64. data/spec/gem_adapter_spec.rb +0 -89
  65. data/spec/models_spec.rb +0 -721
  66. data/spec/polisher_spec.rb +0 -573
  67. data/views/layout.haml +0 -22
  68. data/views/projects/index.haml +0 -42
  69. data/views/projects/index.html.haml +0 -38
  70. data/views/result.haml +0 -9
  71. data/views/sources/index.haml +0 -24
  72. data/views/sources/index.html.haml +0 -26
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/ruby
2
+ # Ruby RPM Spec Updater
3
+ #
4
+ # Simple tool to update the rpm spec of a packaged gem
5
+ # or ruby app.
6
+ #
7
+ # User should specify the location of the rpm spec to
8
+ # manipulate. Script takes an additional option to specify
9
+ # the version of the gem to update to or the location of
10
+ # the gem/gemspec/gemfile source which parse and use.
11
+ #
12
+ # Usage:
13
+ # ruby_rpm_spec_updater.rb <path-to-spec> <optional-source-or-version>
14
+ #
15
+ # Licensed under the MIT License
16
+ # Copyright (C) 2013 Red Hat, Inc.
17
+
18
+ require 'colored'
19
+ require 'polisher'
20
+
21
+ spec_file = ARGV.shift
22
+ source = ARGV.shift
23
+ rpmspec = Polisher::RPMSpec.parse File.read(spec_file)
24
+ source = source.nil? ?
25
+ Polisher::Gem.retrieve(rpmspec.gem_name) :
26
+ Polisher::Upstream.parse(source)
27
+
28
+ rpmspec.update_to(source)
29
+ puts rpmspec.to_string.yellow.bold
@@ -0,0 +1,19 @@
1
+ # Ruby Polisher
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'polisher/core'
7
+ require 'polisher/rpmspec'
8
+ require 'polisher/gem'
9
+ require 'polisher/upstream'
10
+ require 'polisher/gemfile'
11
+ require 'polisher/git'
12
+ require 'polisher/apt'
13
+ require 'polisher/yum'
14
+ require 'polisher/bodhi'
15
+ require 'polisher/rhn'
16
+ require 'polisher/bugzilla'
17
+ require 'polisher/koji'
18
+ require 'polisher/fedora'
19
+ require 'polisher/version_checker'
@@ -0,0 +1,12 @@
1
+ # Polisher APT Operations
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ module Polisher
7
+ class Apt
8
+ def self.version_for(name)
9
+ # TODO
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ # Polisher Bodhi Operations
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'pkgwat'
7
+
8
+ module Polisher
9
+ class Bodhi
10
+ def self.versions_for(name, &bl)
11
+ # fedora pkgwat provides a frontend to bodhi
12
+ updates = Pkgwat.get_updates("rubygem-#{name}", 'all', 'all') # TODO set timeout
13
+ updates.reject! { |u|
14
+ u['stable_version'] == 'None' && u['testing_version'] == "None"
15
+ }
16
+ versions = updates.collect { |u| u['stable_version'] }
17
+ bl.call(:bodhi, name, versions) unless(bl.nil?)
18
+ versions
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ # Polisher Bugzilla Operations
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ module Polisher
7
+ class Bugzilla
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ # Polisher Core Ruby Extensions
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'polisher/rpmspec'
7
+
8
+ class String
9
+ def gem?
10
+ File.extname(self) == ".gem"
11
+ end
12
+
13
+ def gemspec?
14
+ File.extname(self) == ".gemspec"
15
+ end
16
+
17
+ def gemfile?
18
+ File.basename(self) == "Gemfile"
19
+ end
20
+
21
+ def unrpmize
22
+ fmm = Polisher::RPMSpec::FILE_MACRO_MATCHERS
23
+ fmr = Polisher::RPMSpec::FILE_MACRO_REPLACEMENTS
24
+ f = fmm.inject(self) { |file, matcher| file.gsub(matcher, '') }
25
+ f = fmr.keys.inject(f) { |file, r| file.gsub(Regexp.new(r), fmr[r]) }
26
+ f
27
+ end
28
+
29
+ def rpmize
30
+ fmr = Polisher::RPMSpec::FILE_MACRO_REPLACEMENTS.invert
31
+ fmr.keys.inject(self) { |file, r| file.gsub(r, fmr[r]) }
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ # Polisher Errata Operations
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'curb'
7
+
8
+ module Polisher
9
+ class Errata
10
+ def self.client(url)
11
+ @curl ||= begin
12
+ c = Curl::Easy.new
13
+ c.ssl_verify_peer = false
14
+ c.ssl_verify_host = false
15
+ c.http_auth_types = :negotiate
16
+ c.userpwd = ':'
17
+ c.get
18
+ end
19
+
20
+ @curl.url = url
21
+ @curl
22
+ end
23
+
24
+ def self.versions_for(advisory_url, name, &bl)
25
+ url = "#{advisory_url}/builds"
26
+ result = self.client(url).get
27
+ json = JSON.parse result.body_str
28
+ versions =
29
+ json.collect { |tag, builds|
30
+ builds.collect { |build|
31
+ pkg,meta = *build.flatten
32
+ if pkg =~ /^rubygem-#{name}-([^-]*)-.*$/
33
+ $1
34
+ else
35
+ nil
36
+ end
37
+ }
38
+ }.flatten.compact
39
+ bl.call(:errata, name, versions) unless(bl.nil?)
40
+ versions
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # Polisher Fedora Operations
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'curb'
7
+ require 'pkgwat'
8
+
9
+ module Polisher
10
+ class Fedora
11
+ PACKAGE_LIST = 'https://admin.fedoraproject.org/pkgdb/users/packages/'
12
+
13
+ # Retrieve list of gems owned by the specified user
14
+ #
15
+ # @param [String] user Fedora username to lookup
16
+ # @return [Array<String>] list of gems which the user owns/has access to
17
+ def self.gems_owned_by(user)
18
+ curl = Curl::Easy.new("#{PACKAGE_LIST}}#{user}")
19
+ curl.http_get
20
+ packages = curl.body_str
21
+ # TODO instantiate Polisher::Gem instances & return
22
+ Nokogiri::HTML(packages).xpath("//a[@class='PackageName']").
23
+ select { |i| i.text =~ /rubygem-.*/ }.
24
+ collect { |i| i.text.gsub(/rubygem-/, '') }
25
+ end
26
+
27
+ # Retrieve list of the versions of the specified package in the various
28
+ # Fedora releases.
29
+ #
30
+ # @param [String] name name of the package to lookup
31
+ # @param [Callable] bl optional callback to invoke with versions retrieved
32
+ # @return [Array<String>] list of versions in Fedora
33
+ def self.versions_for(name, &bl)
34
+ # XXX bug w/ python-pkgwat, some html content
35
+ # is being returned w/ versions, need to look into
36
+ versions = Pkgwat.get_versions(name)
37
+ versions.reject! { |pkg| pkg['stable_version'] == "None" }
38
+ versions = versions.collect { |pkg| pkg['stable_version'] }
39
+ bl.call(:fedora, name, versions) unless(bl.nil?)
40
+ versions
41
+ end
42
+ end # class Fedora
43
+ end # module Polisher
@@ -0,0 +1,155 @@
1
+ # Polisher Gem Represenation
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'curb'
7
+ require 'json'
8
+ require 'tempfile'
9
+ require 'pathname'
10
+ require 'rubygems/installer'
11
+ require 'active_support/core_ext'
12
+
13
+ require 'polisher/version_checker'
14
+
15
+ module Polisher
16
+ class Gem
17
+ attr_accessor :name
18
+ attr_accessor :version
19
+ attr_accessor :deps
20
+ attr_accessor :dev_deps
21
+ attr_accessor :files
22
+
23
+ def initialize(args={})
24
+ @name = args[:name]
25
+ @version = args[:version]
26
+ @deps = args[:deps] || []
27
+ @dev_deps = args[:dev_deps] || []
28
+ @files = args[:files] || []
29
+ end
30
+
31
+ # Retrieve list of the versions of the specified gem installed locally
32
+ #
33
+ # @param [String] name name of the gem to lookup
34
+ # @param [Callable] bl optional block to invoke with versions retrieved
35
+ # @return [Array<String>] list of versions of gem installed locally
36
+ def self.local_versions_for(name, &bl)
37
+ @local_db ||= ::Gem::Specification.all
38
+ versions = @local_db.select { |s| s.name == name }.collect { |s| s.version }
39
+ bl.call(:local_gem, name, versions) unless(bl.nil?)
40
+ versions
41
+ end
42
+
43
+ # Parse the specified gemspec & return new Gem instance from metadata
44
+ #
45
+ # @param [String,Hash] args contents of actual gemspec of option hash
46
+ # specifying location of gemspec to parse
47
+ # @option args [String] :gemspec path to gemspec to load / parse
48
+ # @return [Polisher::Gem] gem instantiated from gemspec metadata
49
+ def self.parse(args={})
50
+ metadata = {}
51
+
52
+ if args.is_a?(String)
53
+ specj = JSON.parse(args)
54
+ metadata[:name] = specj['name']
55
+ metadata[:version] = specj['version']
56
+ metadata[:deps] = specj['dependencies']['runtime'].collect { |d| d['name'] }
57
+ metadata[:dev_deps] = specj['dependencies']['development'].collect { |d| d['name'] }
58
+
59
+ elsif args.has_key?(:gemspec)
60
+ gemspec = ::Gem::Specification.load(args[:gemspec])
61
+ metadata[:name] = gemspec.name
62
+ metadata[:version] = gemspec.version.to_s
63
+ metadata[:deps] =
64
+ gemspec.dependencies.select { |dep| dep.type == :runtime }.collect { |dep| dep.name }
65
+ metadata[:dev_deps] =
66
+ gemspec.dependencies.select { |dep| dep.type == :development }.collect { |dep| dep.name }
67
+
68
+ elsif args.has_key?(:gem)
69
+ # TODO
70
+ end
71
+
72
+ self.new metadata
73
+ end
74
+
75
+ # Download the gem and return the binary file contents as a string
76
+ # @return [String] binary gem contents
77
+ def download_gem
78
+ gem_path = "https://rubygems.org/gems/#{@name}-#{@version}.gem"
79
+ curl = Curl::Easy.new(gem_path)
80
+ curl.follow_location = true
81
+ curl.http_get
82
+ gemf = curl.body_str
83
+ end
84
+
85
+ # Retrieve the list of files in the gem
86
+ #
87
+ # @return [Array<String>] list of files in the gem
88
+ def refresh_files
89
+ gemf = download_gem
90
+ tgem = Tempfile.new(@name)
91
+ tgem.write gemf
92
+ tgem.close
93
+
94
+ @files = []
95
+ pkg = ::Gem::Installer.new tgem.path, :unpack => true
96
+ Dir.mktmpdir { |dir|
97
+ pkg.unpack dir
98
+ Pathname(dir).find do |path|
99
+ pathstr = path.to_s.gsub(dir, '')
100
+ @files << pathstr unless pathstr.blank?
101
+ end
102
+ }
103
+ @files
104
+ end
105
+
106
+ # Retrieve gem metadata and contents from rubygems.org
107
+ #
108
+ # @param [String] name string name of gem to retrieve
109
+ # @return [Polisher::Gem] representation of gem
110
+ def self.retrieve(name)
111
+ gem_json_path = "https://rubygems.org/api/v1/gems/#{name}.json"
112
+ spec = Curl::Easy.http_get(gem_json_path).body_str
113
+ gem = self.parse spec
114
+ gem.refresh_files
115
+ gem
116
+ end
117
+
118
+ # Retreive versions of gem available on rubygems.org
119
+ #
120
+ # @param [Hash] args hash of options to configure retrieval
121
+ # @option args [Boolean] :recursive indicates if versions of dependencies
122
+ # should also be retrieved
123
+ # @option args [Boolean] :dev_deps indicates if versions of development
124
+ # dependencies should also be retrieved
125
+ # @return [Hash<name,versions>] hash of name to list of versions for gem
126
+ # (and dependencies if specified)
127
+ def versions(args={}, &bl)
128
+ recursive = args[:recursive]
129
+ dev_deps = args[:dev_deps]
130
+
131
+ versions = args[:versions] || {}
132
+ versions.merge!({ self.name => Polisher::VersionChecker.versions_for(self.name, &bl) })
133
+ args[:versions] = versions
134
+
135
+ if recursive
136
+ self.deps.each { |dep|
137
+ unless versions.has_key?(dep)
138
+ gem = Polisher::Gem.retrieve(dep)
139
+ versions.merge! gem.versions(args, &bl)
140
+ end
141
+ }
142
+
143
+ if dev_deps
144
+ self.dev_deps.each { |dep|
145
+ unless versions.has_key?(dep)
146
+ gem = Polisher::Gem.retrieve(dep)
147
+ versions.merge! gem.versions(args, &bl)
148
+ end
149
+ }
150
+ end
151
+ end
152
+ versions
153
+ end
154
+ end # class Gem
155
+ end # module Polisher
@@ -0,0 +1,72 @@
1
+ # Polisher Gemfile Represenation
2
+ #
3
+ # Licensed under the MIT license
4
+ # Copyright (C) 2013 Red Hat, Inc.
5
+
6
+ require 'bundler'
7
+
8
+ require 'polisher/version_checker'
9
+
10
+ # Override bundler's gem registration
11
+ module Bundler
12
+ class << self
13
+ attr_accessor :bundler_gems
14
+
15
+ def init_gems
16
+ Bundler.bundler_gems = []
17
+ end
18
+ end
19
+
20
+ class Dsl
21
+ alias :old_gem :gem
22
+ def gem(name, *args)
23
+ Bundler.bundler_gems ||= []
24
+ version = args.first.is_a?(Hash) ? nil : args.first
25
+ Bundler.bundler_gems << [name, version]
26
+ old_gem(name, *args)
27
+ end
28
+ end
29
+ end
30
+
31
+ module Polisher
32
+ class Gemfile
33
+ include VersionedDependencies
34
+
35
+ # always nil, for interface compatability
36
+ attr_accessor :version
37
+
38
+ attr_accessor :deps
39
+ attr_accessor :dev_deps
40
+
41
+ # always empty array, for interface compatability
42
+ attr_accessor :files
43
+
44
+ def initialize(args={})
45
+ @version = nil
46
+ @deps = args[:deps]
47
+ @dev_deps = args[:dev_deps]
48
+ @files = []
49
+ end
50
+
51
+ # Parse the specified gemfile & return new Gemfile instance from metadata
52
+ #
53
+ # @param [String] path to gemfile to parse
54
+ # @return [Polisher::Gemfile] gemfile instantiated from parsed metadata
55
+ def self.parse(path)
56
+ path,g = File.split(path)
57
+ Dir.chdir(path){
58
+ Bundler.init_gems
59
+ begin
60
+ Bundler::Definition.build(g, nil, false)
61
+ rescue Bundler::GemfileNotFound
62
+ raise ArgumentError, "invalid gemfile: #{path}"
63
+ end
64
+ }
65
+ metadata = {}
66
+ metadata[:deps] = Bundler.bundler_gems.collect { |n,v| n }
67
+ metadata[:dev_deps] = [] # TODO
68
+
69
+ self.new metadata
70
+ end
71
+ end # class Gemfile
72
+ end # module Polisher