yumrepo 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/.document +5 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.rdoc +19 -0
  5. data/Rakefile +34 -0
  6. data/examples/basic.rb +20 -0
  7. data/lib/yumrepo.rb +207 -0
  8. metadata +144 -0
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ gem "rcov", ">= 0"
13
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Sergio Rubio
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = yumrepo
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to yumrepo
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Sergio Rubio. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'lib/yumrepo'
4
+
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
8
+ gem.name = "yumrepo"
9
+ gem.version = YumRepo::VERSION
10
+ gem.homepage = "http://github.com/rubiojr/yumrepo"
11
+ gem.license = "MIT"
12
+ gem.summary = %Q{YUM Repository Metadata handling library}
13
+ gem.description = %Q{YUM Repository Metadata handling library}
14
+ gem.email = "rubiojr@frameos.org"
15
+ gem.authors = ["Sergio Rubio"]
16
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
17
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
18
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
19
+ gem.add_runtime_dependency 'nokogiri'
20
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
21
+ end
22
+ Jeweler::RubygemsDotOrgTasks.new
23
+
24
+ task :default => :build
25
+
26
+ require 'rdoc/task'
27
+ Rake::RDocTask.new do |rdoc|
28
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
29
+
30
+ rdoc.rdoc_dir = 'rdoc'
31
+ rdoc.title = "yumrepo #{version}"
32
+ rdoc.rdoc_files.include('README*')
33
+ rdoc.rdoc_files.include('lib/**/*.rb')
34
+ end
@@ -0,0 +1,20 @@
1
+ $: << File.join(File.dirname(__FILE__), "../lib")
2
+
3
+ require 'yumrepo'
4
+
5
+ settings = YumRepo::Settings.instance
6
+ settings.log_level = :debug
7
+
8
+ pl = YumRepo::PackageList.new "http://rbel.frameos.org/stable/el5/x86_64"
9
+
10
+ count = 0
11
+ pl.each do |p|
12
+ count += 1
13
+ puts "#{p.name}-#{p.version}-#{p.release}"
14
+ puts "Provides: "
15
+ puts " #{p.provides.join("\n ")}"
16
+ puts "Requires: "
17
+ puts " #{p.requires.join("\n ")}"
18
+ end
19
+
20
+ puts "Total packages: #{count}"
@@ -0,0 +1,207 @@
1
+ require 'rubygems'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+ require 'net/https'
5
+ require 'zlib'
6
+ require 'benchmark'
7
+ require 'singleton'
8
+ require 'digest/md5'
9
+ require 'fileutils'
10
+ require 'logger'
11
+
12
+ module YumRepo
13
+
14
+ VERSION = '0.1'
15
+
16
+ def self.bench(msg)
17
+ if defined? $yumrepo_perf_debug
18
+ out = Benchmark.measure do
19
+ yield
20
+ end
21
+ puts msg + out.to_s
22
+ else
23
+ yield
24
+ end
25
+ end
26
+
27
+ class Settings
28
+ include Singleton
29
+ attr_accessor :cache_path, :cache_expire, :cache_enabled, :log_level
30
+
31
+ def initialize
32
+ @cache_path = "#{ENV['HOME']}/.yumrepo/cache/"
33
+ # Cache expire in seconds
34
+ @cache_expire = 3600
35
+ @cache_enabled = true
36
+ @initialized = false
37
+ @log_level = :info
38
+ end
39
+
40
+ def log_level=(level)
41
+ case level
42
+ when :warn
43
+ level = Logger::WARN
44
+ when :debug
45
+ level = Logger::DEBUG
46
+ when :info
47
+ level = Logger::INFO
48
+ when :error
49
+ level = Logger::ERROR
50
+ when :fatal
51
+ level = Logger::FATAL
52
+ else
53
+ level = Logger::DEBUG
54
+ end
55
+ log.level = level
56
+ end
57
+
58
+ def log
59
+ @log ||= Logger.new($stdout)
60
+ end
61
+
62
+ def init
63
+ if @initialized
64
+ log.debug "Settings already initialized"
65
+ return
66
+ end
67
+ log.debug "Initializing settings"
68
+ @initialized = true
69
+ log.debug "Creating cache path #{@cache_path}"
70
+ FileUtils.mkdir_p @cache_path if not File.exist? @cache_path
71
+ end
72
+ end
73
+
74
+ class Repomd
75
+
76
+ #
77
+ # Rasises exception if can't retrieve repomd.xml
78
+ #
79
+ def initialize(url)
80
+ @settings = Settings.instance
81
+ @settings.init
82
+ @url = url
83
+ if @url =~ /\/repodata\/?/
84
+ @url.gsub! '/repodata', ''
85
+ end
86
+ @url_digest = Digest::MD5.hexdigest(@url)
87
+ @repomd_file = File.join(@settings.cache_path, @url_digest, 'repomd.xml')
88
+
89
+ if File.exist?(@repomd_file) and @settings.cache_enabled
90
+ @settings.log.debug "Using catched repomd.xml at #{@repomd_file}"
91
+ f = open @repomd_file
92
+ else
93
+ @settings.log.debug "Fetching repomd.xml from #{@url}"
94
+ f = open "#{@url}/repodata/repomd.xml"
95
+ if @settings.cache_enabled
96
+ FileUtils.mkdir_p File.join(@settings.cache_path, @url_digest)
97
+ @settings.log.debug "Caching repomd.xml for #{@url} at #{@repomd_file}"
98
+ File.open(File.join(@settings.cache_path, @url_digest, 'repomd.xml'), 'w') do |xml|
99
+ xml.puts f.read
100
+ end
101
+ f = open(@repomd_file)
102
+ end
103
+ end
104
+ @repomd = Nokogiri::XML(f)
105
+ end
106
+
107
+ def filelists
108
+ fl = []
109
+ @repomd.xpath("/xmlns:repomd/xmlns:data[@type=\"filelists\"]/xmlns:location").each do |f|
110
+ fl << File.join(@url, f['href'])
111
+ end
112
+ fl
113
+ end
114
+
115
+ def primary
116
+ pl = []
117
+ @repomd.xpath("/xmlns:repomd/xmlns:data[@type=\"primary\"]/xmlns:location").each do |p|
118
+ pl << File.join(@url, p['href'])
119
+ end
120
+ @primary_xml = File.join(@settings.cache_path, @url_digest, "primary.xml.gz")
121
+ if File.exist?(@primary_xml) and @settings.cache_enabled
122
+ @settings.log.debug "Using catched primary.xml.gz at #{@primary_xml}"
123
+ f = open @primary_xml
124
+ else
125
+ @settings.log.debug "Fetching primary.xml.gz from #{pl.first}"
126
+ f = open pl.first
127
+ if @settings.cache_enabled
128
+ FileUtils.mkdir_p File.join(@settings.cache_path, @url_digest)
129
+ @settings.log.debug "Caching primary.xml.gz for #{@url} at #{@primary_xml}"
130
+ File.open(@primary_xml, 'w') do |xml|
131
+ xml.puts f.read
132
+ end
133
+ end
134
+ end
135
+ @primary_xml
136
+ end
137
+ end
138
+
139
+ class PackageList
140
+
141
+ def initialize(url)
142
+ @url = url
143
+ @xml_file = open(Repomd.new(url).primary)
144
+ end
145
+
146
+ def each
147
+ all.each do |p|
148
+ yield p
149
+ end
150
+ end
151
+
152
+ def all
153
+ buf = ''
154
+ YumRepo.bench("Zlib::GzipReader.read") do
155
+ buf = Zlib::GzipReader.new(@xml_file).read
156
+ end
157
+
158
+ packages = []
159
+ YumRepo.bench("Building Package Objects") do
160
+ d = Nokogiri::XML::Reader(buf)
161
+ d.each do |n|
162
+ if n.name == 'package' and not n.node_type == Nokogiri::XML::Reader::TYPE_END_ELEMENT
163
+ packages << Package.new(n.outer_xml)
164
+ end
165
+ end
166
+ end
167
+ packages
168
+ end
169
+ end
170
+
171
+ class Package
172
+ def initialize(xml)
173
+ @xml = xml
174
+ end
175
+
176
+ def doc
177
+ @doc ||= Nokogiri::XML(@xml)
178
+ end
179
+
180
+ def name
181
+ doc.xpath('/xmlns:package/xmlns:name').text
182
+ end
183
+
184
+ def version
185
+ doc.xpath('/xmlns:package/xmlns:version/@ver').text
186
+ end
187
+ def release
188
+ doc.xpath('/xmlns:package/xmlns:version/@rel').text
189
+ end
190
+
191
+ def provides
192
+ doc.xpath('/xmlns:package/xmlns:format/rpm:provides/rpm:entry').map do |pr|
193
+ {
194
+ :name => pr.at_xpath('./@name').text
195
+ }
196
+ end
197
+ end
198
+ def requires
199
+ doc.xpath('/xmlns:package/xmlns:format/rpm:requires/rpm:entry').map do |pr|
200
+ {
201
+ :name => pr.at_xpath('./@name').text
202
+ }
203
+ end
204
+ end
205
+ end
206
+
207
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yumrepo
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Sergio Rubio
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-08-11 00:00:00 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ version_requirements: &id001 !ruby/object:Gem::Requirement
21
+ none: false
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ hash: 3
26
+ segments:
27
+ - 0
28
+ version: "0"
29
+ type: :development
30
+ requirement: *id001
31
+ prerelease: false
32
+ name: shoulda
33
+ - !ruby/object:Gem::Dependency
34
+ version_requirements: &id002 !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ hash: 23
40
+ segments:
41
+ - 1
42
+ - 0
43
+ - 0
44
+ version: 1.0.0
45
+ type: :development
46
+ requirement: *id002
47
+ prerelease: false
48
+ name: bundler
49
+ - !ruby/object:Gem::Dependency
50
+ version_requirements: &id003 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ hash: 7
56
+ segments:
57
+ - 1
58
+ - 5
59
+ - 2
60
+ version: 1.5.2
61
+ type: :development
62
+ requirement: *id003
63
+ prerelease: false
64
+ name: jeweler
65
+ - !ruby/object:Gem::Dependency
66
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ requirement: *id004
77
+ prerelease: false
78
+ name: rcov
79
+ - !ruby/object:Gem::Dependency
80
+ version_requirements: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :runtime
90
+ requirement: *id005
91
+ prerelease: false
92
+ name: nokogiri
93
+ description: YUM Repository Metadata handling library
94
+ email: rubiojr@frameos.org
95
+ executables: []
96
+
97
+ extensions: []
98
+
99
+ extra_rdoc_files:
100
+ - LICENSE.txt
101
+ - README.rdoc
102
+ files:
103
+ - .document
104
+ - Gemfile
105
+ - LICENSE.txt
106
+ - README.rdoc
107
+ - Rakefile
108
+ - examples/basic.rb
109
+ - lib/yumrepo.rb
110
+ homepage: http://github.com/rubiojr/yumrepo
111
+ licenses:
112
+ - MIT
113
+ post_install_message:
114
+ rdoc_options: []
115
+
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
135
+ version: "0"
136
+ requirements: []
137
+
138
+ rubyforge_project:
139
+ rubygems_version: 1.8.5
140
+ signing_key:
141
+ specification_version: 3
142
+ summary: YUM Repository Metadata handling library
143
+ test_files: []
144
+