ropes 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -14,7 +14,7 @@ It will generate the following files:
14
14
 
15
15
  ## Current status
16
16
 
17
- As of 0.0.1, it generates only `Releases`, `Releases.gpg`, `Packages` and `Packages.gz`.
17
+ As of 0.2.1, it generates only `Releases`, `Releases.gpg`, `Packages` and `Packages.gz`.
18
18
  This is enough to get a basic Ubuntu repository working. There is no yum support.
19
19
 
20
20
  ## Installation
@@ -51,8 +51,14 @@ for you.
51
51
 
52
52
  repo.add_file_by_path("some_custom_package.deb")
53
53
 
54
+ # For amd64 files
54
55
  File.open("Packages", "w") do |file|
55
- file.write repo.packages_file
56
+ file.write repo.packages_file("amd64")
57
+ end
58
+
59
+ # For i386
60
+ File.open("Packages", "w") do |file|
61
+ file.write repo.packages_file("i386")
56
62
  end
57
63
 
58
64
  File.open("Release", "w") do |file|
@@ -63,8 +69,14 @@ for you.
63
69
  file.write repo.release_file_gpg("/path/to/your/gpg.key")
64
70
  end
65
71
 
72
+ # For amd64
73
+ File.open("Packages.gz", "w") do |file|
74
+ file.write repo.packages_file_gz("amd64")
75
+ end
76
+
77
+ # For i386
66
78
  File.open("Packages.gz", "w") do |file|
67
- file.write repo.packages_file_gz
79
+ file.write repo.packages_file_gz("amd64")
68
80
  end
69
81
 
70
82
  ## Contributing
data/lib/ropes.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "ropes/version"
2
- require "ropes/repository"
2
+ require "ropes/repository/debian"
3
3
 
4
4
  module Ropes
5
5
 
@@ -0,0 +1,179 @@
1
+ require 'debeasy'
2
+ require 'stringio'
3
+ require 'zlib'
4
+ require 'tempfile'
5
+ require 'digest'
6
+ require 'gpgme'
7
+ require 'uuid'
8
+
9
+ module Ropes
10
+
11
+ class Error < RuntimeError; end
12
+ class InvalidRepositoryType < Error; end
13
+
14
+ module Repository
15
+ class Apt
16
+
17
+ def initialize(options)
18
+ missing_options = %w{
19
+ origin
20
+ type
21
+ distribution
22
+ version
23
+ architectures
24
+ components
25
+ description
26
+ package_base}.reject do |required_option|
27
+ options.has_key?(required_option.to_sym)
28
+ end
29
+
30
+ raise "Missing options: #{missing_options.join(", ")}" unless missing_options.empty?
31
+
32
+ raise Error, "Architectures must be an array" unless options[:architectures].is_a? Array
33
+
34
+ @release_file = nil
35
+ @packages_file = nil
36
+ @packages_field_gz = nil
37
+
38
+ @options = options
39
+ @packages = []
40
+ @field_order = %w{
41
+ package
42
+ priority
43
+ section
44
+ installed_size
45
+ maintainer
46
+ architecture
47
+ source
48
+ version
49
+ depends
50
+ filename
51
+ size
52
+ MD5sum
53
+ SHA1
54
+ SHA256
55
+ description
56
+ description-md5
57
+ bugs
58
+ origin
59
+ supported
60
+ }
61
+ @mandatory_fields = %w{
62
+ package
63
+ version
64
+ architecture
65
+ maintainer
66
+ description
67
+ }
68
+ end
69
+
70
+ def add_file_by_path(path)
71
+ metadata = Debeasy.read(path).to_hash
72
+ if validate_metadata(metadata).empty?
73
+ @packages << metadata
74
+ else
75
+ raise "Missing mandatory fields on package: #{validate_metadata(metadata).join(", ")}"
76
+ end
77
+ end
78
+
79
+ def add_file_by_info(package)
80
+ if validate_metadata(package).empty?
81
+ if package.is_a? Hash
82
+ @packages << package
83
+ else
84
+ raise "Package metadata must be in hash format"
85
+ end
86
+ else
87
+ raise "Missing mandatory fields on package: #{validate_metadata(package).join(", ")}"
88
+ end
89
+ end
90
+
91
+ # Get the Packages file as a string
92
+
93
+ def packages_file(arch)
94
+ packages_for_arch = @packages.select {|p| p["architecture"] == arch}
95
+ entries = packages_for_arch.map do |package|
96
+ lines = []
97
+ @field_order.each do |field|
98
+ if package[field] != nil
99
+ case field
100
+ when "filename"
101
+ lines << packages_line(field.capitalize, "#{@options[:package_base]}/#{package[field]}")
102
+ when "installed_size"
103
+ lines << packages_line("Installed-Size", package[field])
104
+ when "SHA1", "SHA256", "MD5sum"
105
+ lines << packages_line(field, package[field])
106
+ else
107
+ lines << packages_line(field.capitalize, package[field])
108
+ end
109
+ end
110
+ end
111
+ lines.join("\n")
112
+ end
113
+ if entries.empty?
114
+ ""
115
+ else
116
+ entries.join("\n\n") + "\n"
117
+ end
118
+ end
119
+
120
+ # Get the Packages file as a gzip'ed string
121
+
122
+ def packages_file_gz(arch)
123
+ io = StringIO.new("w")
124
+ gz = Zlib::GzipWriter.new(io)
125
+ gz.write(packages_file(arch))
126
+ gz.close
127
+ io.string
128
+ end
129
+
130
+ # Get the Release file as a string
131
+
132
+ def release_file
133
+ lines = []
134
+ lines << "Origin: #{@options[:origin]}"
135
+ lines << "Label: #{@options[:origin]}"
136
+ lines << "Suite: #{@options[:distribution]}"
137
+ lines << "Version: #{@options[:version]}"
138
+ lines << "Codename: #{@options[:distribution]}"
139
+ lines << "Date: #{Time.new.utc.strftime '%a, %d %b %Y %H:%M:%S UTC'}"
140
+ lines << "Architectures: #{@options[:architectures].join(" ")}"
141
+ lines << "Components: #{@options[:components]}"
142
+ lines << "Description: #{@options[:description]}"
143
+ lines << "MD5Sum:"
144
+ @options[:architectures].each do |arch|
145
+ # Have to create the files in real life to get the real size
146
+ temp_packages_file = Tempfile.new("Packages")
147
+ temp_packages_file.write packages_file(arch)
148
+ temp_packages_file_gz = Tempfile.new("Packages.gz")
149
+ temp_packages_file_gz.write packages_file_gz(arch)
150
+ lines << " #{Digest::MD5.hexdigest(packages_file(arch))} #{temp_packages_file.size} #{@options[:components]}/binary-#{arch}/Packages"
151
+ lines << " #{Digest::MD5.hexdigest(packages_file_gz(arch))} #{temp_packages_file_gz.size} #{@options[:components]}/binary-#{arch}/Packages.gz"
152
+ end
153
+ lines.join("\n") + "\n"
154
+ end
155
+
156
+ # Get detached GPG signature of Release file
157
+
158
+ def release_file_gpg(path_to_gpgkey)
159
+ GPGME::Key.import(File.open(path_to_gpgkey))
160
+ GPGME::Crypto.new.sign(release_file, {
161
+ :mode => GPGME::SIG_MODE_DETACH,
162
+ :armor => true
163
+ })
164
+ end
165
+
166
+ private
167
+
168
+
169
+ def packages_line(field, value)
170
+ "#{field}: #{value}"
171
+ end
172
+
173
+ def validate_metadata(metadata_hash)
174
+ @mandatory_fields.reject {|field| metadata_hash.has_key?(field)}
175
+ end
176
+
177
+ end
178
+ end
179
+ end
File without changes
data/lib/ropes/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ropes
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/ropes.gemspec CHANGED
@@ -23,4 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rake"
24
24
  spec.add_dependency "debeasy"
25
25
  spec.add_dependency "gpgme"
26
+ spec.add_dependency "arr-pm"
27
+ spec.add_dependency "nokogiri"
28
+ spec.add_dependency "uuid"
26
29
  end
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ropes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Andy Sykes
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-10-19 00:00:00.000000000 Z
12
+ date: 2013-12-16 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
@@ -27,48 +30,101 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rake
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: debeasy
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - '>='
51
+ - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: '0'
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - '>='
59
+ - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: gpgme
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
- - - '>='
67
+ - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
69
  version: '0'
62
70
  type: :runtime
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - '>='
75
+ - - ! '>='
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0'
69
- description: |-
70
- Build apt and yum repositories from
71
- a directory, or from supplied information
78
+ - !ruby/object:Gem::Dependency
79
+ name: arr-pm
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: nokogiri
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: uuid
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: ! "Build apt and yum repositories from\n a directory,
127
+ or from supplied information"
72
128
  email:
73
129
  - github@tinycat.co.uk
74
130
  executables: []
@@ -81,31 +137,33 @@ files:
81
137
  - README.md
82
138
  - Rakefile
83
139
  - lib/ropes.rb
84
- - lib/ropes/repository.rb
140
+ - lib/ropes/repository/apt.rb
141
+ - lib/ropes/repository/yum.rb
85
142
  - lib/ropes/version.rb
86
143
  - ropes.gemspec
87
144
  homepage: https://github.com/andytinycat/ropes
88
145
  licenses:
89
146
  - MIT
90
- metadata: {}
91
147
  post_install_message:
92
148
  rdoc_options: []
93
149
  require_paths:
94
150
  - lib
95
151
  required_ruby_version: !ruby/object:Gem::Requirement
152
+ none: false
96
153
  requirements:
97
- - - '>='
154
+ - - ! '>='
98
155
  - !ruby/object:Gem::Version
99
156
  version: '0'
100
157
  required_rubygems_version: !ruby/object:Gem::Requirement
158
+ none: false
101
159
  requirements:
102
- - - '>='
160
+ - - ! '>='
103
161
  - !ruby/object:Gem::Version
104
162
  version: '0'
105
163
  requirements: []
106
164
  rubyforge_project:
107
- rubygems_version: 2.1.9
165
+ rubygems_version: 1.8.25
108
166
  signing_key:
109
- specification_version: 4
167
+ specification_version: 3
110
168
  summary: Build apt and yum repositories with Ruby
111
169
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: f0340a39d71d97eed45a3581d0b888b7baecaf26
4
- data.tar.gz: aa6e407db435d64f5357122f501a378fa40cd60b
5
- SHA512:
6
- metadata.gz: f487454858ff5e087d7fd48df9c6836d61ec5d44b3eecd3f3f5ebf393c032a19c16ad78dd50463cd0a121e0ded135781780390ff895cc37300426a97775b927a
7
- data.tar.gz: ef54892b3d5374d2817c31f00f6d193f8346ffaf8df4b98e6a4d2d536efaadf3e22f680fe56da8c85169d1007f19ae967f4aa902ef1ca1a97859401632583320
@@ -1,178 +0,0 @@
1
- require 'debeasy'
2
- require 'stringio'
3
- require 'zlib'
4
- require 'tempfile'
5
- require 'digest'
6
- require 'gpgme'
7
- require 'uuid'
8
-
9
- module Ropes
10
-
11
- class Error < RuntimeError; end
12
- class InvalidRepositoryType < Error; end
13
-
14
- class Repository
15
-
16
- def initialize(options)
17
- missing_options = %w{
18
- origin
19
- type
20
- distribution
21
- version
22
- architectures
23
- components
24
- description
25
- package_base}.reject do |required_option|
26
- options.has_key?(required_option.to_sym)
27
- end
28
-
29
- raise "Missing options: #{missing_options.join(", ")}" unless missing_options.empty?
30
-
31
- raise InvalidRepositoryType, "Repository type #{options[:type]} is neither :apt or :yum" unless options[:type] == :yum or options[:type] == :apt
32
- raise Error, "Architectures must be an array" unless options[:architectures].is_a? Array
33
-
34
- @release_file = nil
35
- @packages_file = nil
36
- @packages_field_gz = nil
37
-
38
- @options = options
39
- @packages = []
40
- @field_order = %w{
41
- package
42
- priority
43
- section
44
- installed_size
45
- maintainer
46
- architecture
47
- source
48
- version
49
- depends
50
- filename
51
- size
52
- MD5sum
53
- SHA1
54
- SHA256
55
- description
56
- description-md5
57
- bugs
58
- origin
59
- supported
60
- }
61
- @mandatory_fields = %w{
62
- package
63
- version
64
- architecture
65
- maintainer
66
- description
67
- }
68
- end
69
-
70
- def add_file_by_path(path)
71
- metadata = Debeasy.read(path).to_hash
72
- if validate_metadata(metadata).empty?
73
- @packages << metadata
74
- else
75
- raise "Missing mandatory fields on package: #{validate_metadata(metadata).join(", ")}"
76
- end
77
- end
78
-
79
- def add_file_by_info(package)
80
- if validate_metadata(package).empty?
81
- if package.is_a? Hash
82
- @packages << package
83
- else
84
- raise "Package metadata must be in hash format"
85
- end
86
- else
87
- raise "Missing mandatory fields on package: #{validate_metadata(package).join(", ")}"
88
- end
89
- end
90
-
91
- # Get the Packages file as a string
92
-
93
- def packages_file(arch)
94
- packages_for_arch = @packages.select {|p| p["architecture"] == arch}
95
- entries = packages_for_arch.map do |package|
96
- lines = []
97
- @field_order.each do |field|
98
- if package[field] != nil
99
- case field
100
- when "filename"
101
- lines << packages_line(field.capitalize, "#{@options[:package_base]}/#{package[field]}")
102
- when "installed_size"
103
- lines << packages_line("Installed-Size", package[field])
104
- when "SHA1", "SHA256", "MD5sum"
105
- lines << packages_line(field, package[field])
106
- else
107
- lines << packages_line(field.capitalize, package[field])
108
- end
109
- end
110
- end
111
- lines.join("\n")
112
- end
113
- if entries.empty?
114
- ""
115
- else
116
- entries.join("\n\n") + "\n"
117
- end
118
- end
119
-
120
- # Get the Packages file as a gzip'ed string
121
-
122
- def packages_file_gz(arch)
123
- io = StringIO.new("w")
124
- gz = Zlib::GzipWriter.new(io)
125
- gz.write(packages_file(arch))
126
- gz.close
127
- io.string
128
- end
129
-
130
- # Get the Release file as a string
131
-
132
- def release_file
133
- lines = []
134
- lines << "Origin: #{@options[:origin]}"
135
- lines << "Label: #{@options[:origin]}"
136
- lines << "Suite: #{@options[:distribution]}"
137
- lines << "Version: #{@options[:version]}"
138
- lines << "Codename: #{@options[:distribution]}"
139
- lines << "Date: #{Time.new.utc.strftime '%a, %d %b %Y %H:%M:%S UTC'}"
140
- lines << "Architectures: #{@options[:architectures].join(" ")}"
141
- lines << "Components: #{@options[:components]}"
142
- lines << "Description: #{@options[:description]}"
143
- lines << "MD5Sum:"
144
- @options[:architectures].each do |arch|
145
- # Have to create the files in real life to get the real size
146
- temp_packages_file = Tempfile.new("Packages")
147
- temp_packages_file.write packages_file(arch)
148
- temp_packages_file_gz = Tempfile.new("Packages.gz")
149
- temp_packages_file_gz.write packages_file_gz(arch)
150
- lines << " #{Digest::MD5.hexdigest(packages_file(arch))} #{temp_packages_file.size} #{@options[:components]}/binary-#{arch}/Packages"
151
- lines << " #{Digest::MD5.hexdigest(packages_file_gz(arch))} #{temp_packages_file_gz.size} #{@options[:components]}/binary-#{arch}/Packages.gz"
152
- end
153
- lines.join("\n") + "\n"
154
- end
155
-
156
- # Get detached GPG signature of Release file
157
-
158
- def release_file_gpg(path_to_gpgkey)
159
- GPGME::Key.import(File.open(path_to_gpgkey))
160
- GPGME::Crypto.new.sign(release_file, {
161
- :mode => GPGME::SIG_MODE_DETACH,
162
- :armor => true
163
- })
164
- end
165
-
166
- private
167
-
168
-
169
- def packages_line(field, value)
170
- "#{field}: #{value}"
171
- end
172
-
173
- def validate_metadata(metadata_hash)
174
- @mandatory_fields.reject {|field| metadata_hash.has_key?(field)}
175
- end
176
-
177
- end
178
- end