packo 0.0.1.alpha.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 (107) hide show
  1. data/bin/packo +78 -0
  2. data/bin/packo-base +24 -0
  3. data/bin/packo-build +24 -0
  4. data/bin/packo-db +24 -0
  5. data/bin/packo-env +24 -0
  6. data/bin/packo-files +24 -0
  7. data/bin/packo-profile +24 -0
  8. data/bin/packo-repository +24 -0
  9. data/bin/packo-select +24 -0
  10. data/lib/packo.rb +186 -0
  11. data/lib/packo/cli.rb +79 -0
  12. data/lib/packo/cli/base.rb +554 -0
  13. data/lib/packo/cli/build.rb +488 -0
  14. data/lib/packo/cli/database.rb +55 -0
  15. data/lib/packo/cli/database/definition.rb +65 -0
  16. data/lib/packo/cli/database/helpers.rb +20 -0
  17. data/lib/packo/cli/environment.rb +45 -0
  18. data/lib/packo/cli/files.rb +153 -0
  19. data/lib/packo/cli/profile.rb +31 -0
  20. data/lib/packo/cli/repository.rb +561 -0
  21. data/lib/packo/cli/repository/binary.rb +74 -0
  22. data/lib/packo/cli/repository/helpers.rb +20 -0
  23. data/lib/packo/cli/repository/repository.rb +48 -0
  24. data/lib/packo/cli/repository/source.rb +91 -0
  25. data/lib/packo/cli/repository/virtual.rb +53 -0
  26. data/lib/packo/cli/select.rb +61 -0
  27. data/lib/packo/do.rb +249 -0
  28. data/lib/packo/environment.rb +269 -0
  29. data/lib/packo/extensions.rb +70 -0
  30. data/lib/packo/flags.rb +64 -0
  31. data/lib/packo/host.rb +121 -0
  32. data/lib/packo/models.rb +171 -0
  33. data/lib/packo/models/installed_package.rb +190 -0
  34. data/lib/packo/models/installed_package/content.rb +50 -0
  35. data/lib/packo/models/installed_package/dependency.rb +39 -0
  36. data/lib/packo/models/repository.rb +209 -0
  37. data/lib/packo/models/repository/binary.rb +32 -0
  38. data/lib/packo/models/repository/binary/mirror.rb +35 -0
  39. data/lib/packo/models/repository/package.rb +73 -0
  40. data/lib/packo/models/repository/package/binary.rb +34 -0
  41. data/lib/packo/models/repository/package/binary/build.rb +36 -0
  42. data/lib/packo/models/repository/package/source.rb +36 -0
  43. data/lib/packo/models/repository/package/source/feature.rb +36 -0
  44. data/lib/packo/models/repository/package/source/flavor.rb +36 -0
  45. data/lib/packo/models/repository/package/virtual.rb +32 -0
  46. data/lib/packo/models/repository/source.rb +30 -0
  47. data/lib/packo/models/repository/virtual.rb +30 -0
  48. data/lib/packo/models/selector.rb +34 -0
  49. data/lib/packo/models/tag.rb +30 -0
  50. data/lib/packo/package.rb +239 -0
  51. data/lib/packo/package/blocker.rb +100 -0
  52. data/lib/packo/package/blockers.rb +40 -0
  53. data/lib/packo/package/dependencies.rb +40 -0
  54. data/lib/packo/package/dependency.rb +100 -0
  55. data/lib/packo/package/feature.rb +55 -0
  56. data/lib/packo/package/features.rb +105 -0
  57. data/lib/packo/package/flavor.rb +101 -0
  58. data/lib/packo/package/tags.rb +60 -0
  59. data/lib/packo/package/tags/expression.rb +130 -0
  60. data/lib/packo/package/tags/expression/group.rb +28 -0
  61. data/lib/packo/package/tags/expression/logic.rb +48 -0
  62. data/lib/packo/package/tags/expression/name.rb +28 -0
  63. data/lib/packo/profile.rb +174 -0
  64. data/lib/packo/rbuild.rb +22 -0
  65. data/lib/packo/rbuild/behaviors.rb +20 -0
  66. data/lib/packo/rbuild/behaviors/default.rb +27 -0
  67. data/lib/packo/rbuild/feature.rb +64 -0
  68. data/lib/packo/rbuild/features.rb +65 -0
  69. data/lib/packo/rbuild/flavor.rb +67 -0
  70. data/lib/packo/rbuild/module.rb +40 -0
  71. data/lib/packo/rbuild/modules.rb +27 -0
  72. data/lib/packo/rbuild/modules/building.rb +24 -0
  73. data/lib/packo/rbuild/modules/building/autotools.rb +315 -0
  74. data/lib/packo/rbuild/modules/building/cmake.rb +38 -0
  75. data/lib/packo/rbuild/modules/building/patch.rb +84 -0
  76. data/lib/packo/rbuild/modules/building/rake.rb +74 -0
  77. data/lib/packo/rbuild/modules/building/strip.rb +41 -0
  78. data/lib/packo/rbuild/modules/misc.rb +26 -0
  79. data/lib/packo/rbuild/modules/misc/fetcher.rb +177 -0
  80. data/lib/packo/rbuild/modules/misc/fetching.rb +22 -0
  81. data/lib/packo/rbuild/modules/misc/fetching/git.rb +57 -0
  82. data/lib/packo/rbuild/modules/misc/fetching/github.rb +31 -0
  83. data/lib/packo/rbuild/modules/misc/fetching/gnu.rb +59 -0
  84. data/lib/packo/rbuild/modules/misc/fetching/mercurial.rb +51 -0
  85. data/lib/packo/rbuild/modules/misc/fetching/sourceforge.rb +47 -0
  86. data/lib/packo/rbuild/modules/misc/fetching/subversion.rb +51 -0
  87. data/lib/packo/rbuild/modules/misc/fetching/wget.rb +57 -0
  88. data/lib/packo/rbuild/modules/misc/unpacker.rb +70 -0
  89. data/lib/packo/rbuild/modules/misc/unpacking.rb +23 -0
  90. data/lib/packo/rbuild/modules/misc/unpacking/lzma.rb +34 -0
  91. data/lib/packo/rbuild/modules/misc/unpacking/tar.rb +35 -0
  92. data/lib/packo/rbuild/modules/misc/unpacking/xz.rb +34 -0
  93. data/lib/packo/rbuild/modules/misc/unpacking/zip.rb +26 -0
  94. data/lib/packo/rbuild/modules/packaging.rb +20 -0
  95. data/lib/packo/rbuild/modules/packaging/pko.rb +78 -0
  96. data/lib/packo/rbuild/package.rb +281 -0
  97. data/lib/packo/rbuild/package/manifest.rb +169 -0
  98. data/lib/packo/rbuild/stages.rb +171 -0
  99. data/lib/packo/rbuild/stages/callbacks.rb +96 -0
  100. data/lib/packo/rbuild/stages/stage.rb +50 -0
  101. data/lib/packo/repository.rb +95 -0
  102. data/lib/packo/repository/binary.rb +116 -0
  103. data/lib/packo/repository/source.rb +77 -0
  104. data/lib/packo/repository/virtual.rb +66 -0
  105. data/lib/packo/system.rb +53 -0
  106. data/lib/packo/version.rb +26 -0
  107. metadata +276 -0
@@ -0,0 +1,488 @@
1
+ # encoding: utf-8
2
+ #--
3
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
4
+ #
5
+ # This file is part of packo.
6
+ #
7
+ # packo is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # packo is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with packo. If not, see <http://www.gnu.org/licenses/>.
19
+ #++
20
+
21
+ require 'nokogiri'
22
+ require 'digest/sha1'
23
+
24
+ require 'packo'
25
+ require 'packo/rbuild'
26
+
27
+ module Packo; module CLI
28
+
29
+ class Build < Thor
30
+ include Thor::Actions
31
+
32
+ class_option :help, type: :boolean, desc: 'Show help usage'
33
+
34
+ desc 'package PACKAGE... [OPTIONS]', 'Create packages of the matching names'
35
+ method_option :output, type: :string, default: System.env[:TMP], aliases: '-o', desc: 'The directory where to save packages'
36
+ method_option :wipe, type: :boolean, default: false, aliases: '-w', desc: 'Wipes the package directory before building it'
37
+ method_option :ask, type: :boolean, default: false, aliases: '-a', desc: 'Prompt the user if he want to continue building or not'
38
+ method_option :repository, type: :string, aliases: '-r', desc: 'Set a specific source repository'
39
+ method_option :execute, type: :string, aliases: '-x', desc: 'Create a package from an executed command instead of from an RBuild'
40
+ method_option :bump, type: :boolean, default: true, aliases: '-b', desc: 'Bump revision when creating a package from command if package is installed'
41
+ method_option :inspect, type: :boolean, default: false, aliases: '-i', desc: 'Inspect the list of files that will be included in the package in EDITOR'
42
+ def package (*packages)
43
+ if command = options[:execute]
44
+ if System.env[:SANDBOX_ACTIVE] || System.env[:FAKED_MODE]
45
+ CLI.warn "`packo build -x` may not work properly, try with `packo-build -x` if it fails.\n\n"
46
+ end
47
+
48
+ package = Package.parse(packages.first)
49
+
50
+ unless package.name && package.version
51
+ CLI.fatal 'You have to pass a valid package name and version, like package-0.2'
52
+ exit 1
53
+ end
54
+
55
+ package = RBuild::Package.define(package.name, package.version) {
56
+ tags *package.tags
57
+
58
+ description "Built in: `#{Dir.pwd}` with `#{command}`"
59
+ maintainer ENV['USER']
60
+ }
61
+
62
+ package.avoid RBuild::Behaviors::Default
63
+
64
+ package.clean!
65
+ package.create!
66
+
67
+ tmp = Tempfile.new('packo')
68
+ dir = "#{System.env[:TMP]}/#{Process.pid}"
69
+
70
+ tmp.write %{
71
+ #! /bin/sh
72
+
73
+ cd "#{Dir.pwd}"
74
+
75
+ #{command}
76
+
77
+ exit $?
78
+ }
79
+
80
+ tmp.chmod 0700
81
+ tmp.close
82
+
83
+ Packo.sh 'installwatch', "--logfile=#{package.tempdir}/newfiles.log", "--exclude=#{Dir.pwd}",
84
+ "--root=#{package.workdir}", '--transl=yes', '--backup=no', tmp.path
85
+
86
+ inspect = options[:inspect]
87
+
88
+ package.before :pack, priority: -42 do
89
+ files = File.new("#{tempdir}/newfiles", 'w')
90
+
91
+ files.print File.new("#{tempdir}/newfiles.log", 'r').lines.map {|line| line.strip!
92
+ whole, type = line.match(/^.*?\t(.*?)\t/).to_a
93
+
94
+ case type
95
+ when 'chmod', 'open'
96
+ whole, file = line.match(/.*?\t.*?\t(.*?)(\t|$)/).to_a
97
+
98
+ next if file.match(%r[^(/dev|#{Regexp.escape(Dir.pwd)}|/tmp)(/|$)])
99
+
100
+ file
101
+
102
+ when 'symlink'
103
+ whole, to, file = line.match(/.*?\t.*?\t(.*?)\t(.*?)(\t|$)/).to_a
104
+
105
+ "#{file} -> #{to}"
106
+ end
107
+ }.compact.uniq.sort.join("\n")
108
+
109
+ files.close
110
+
111
+ if inspect
112
+ Packo.sh System.env[:EDITOR] || 'vi', files.path
113
+ end
114
+
115
+ links = []
116
+
117
+ File.new("#{tempdir}/newfiles", 'r').lines.each {|line|
118
+ whole, file, link = line.match(/^(.*?)(?: -> (.*?))?$/).to_a
119
+
120
+ FileUtils.mkpath "#{distdir}/#{File.dirname(file)}"
121
+
122
+ if link
123
+ links << [link, file]
124
+ else
125
+ FileUtils.cp "#{workdir}/TRANSL/#{file}", "#{distdir}/#{file}"
126
+ end
127
+ }
128
+
129
+ links.each {|(link, file)|
130
+ FileUtils.ln_sf link, "#{distdir}/#{file}" rescue nil
131
+ }
132
+ end
133
+
134
+ package.before :pack! do
135
+ if inspect
136
+ Packo.sh System.env[:EDITOR] || 'vi', "#{directory}/manifest.xml"
137
+ end
138
+ end
139
+
140
+ if options[:bump]
141
+ require 'packo/models'
142
+
143
+ if !Models.search_installed(package.to_s).empty?
144
+ package.revision = Models.search_installed(package.to_s).first.revision + 1
145
+ end
146
+ end
147
+
148
+ begin
149
+ package.build {|stage|
150
+ CLI.info "Executing #{stage.name}"
151
+ }
152
+
153
+ CLI.info "Succesfully built #{package}"
154
+ rescue Exception => e
155
+ CLI.fatal "Failed to build #{package}"
156
+ CLI.fatal e.message
157
+ Packo.debug e
158
+ end
159
+
160
+ exit 0
161
+ end
162
+
163
+ Environment.new {|env|
164
+ if !env[:ARCH] || !env[:KERNEL] || !env[:LIBC] || !env[:COMPILER]
165
+ CLI.fatal 'You have to set ARCH, KERNEL, LIBC and COMPILER to build packages.'
166
+ exit 1
167
+ end
168
+ }
169
+
170
+ packages.map {|package|
171
+ if package.end_with?('.rbuild')
172
+ package
173
+ else
174
+ require 'packo/models'
175
+
176
+ packages = Models.search(package, options[:repository])
177
+
178
+ names = packages.group_by {|package|
179
+ "#{package.tags}/#{package.name}"
180
+ }.map {|(name, package)| name}.uniq
181
+
182
+ if names.length == 0
183
+ CLI.fatal "No package matches #{package}"
184
+
185
+ exit 10
186
+ elsif names.length > 1
187
+ CLI.fatal "More than one package matches: #{package}"
188
+
189
+ names.each {|name|
190
+ puts " #{name}"
191
+ }
192
+
193
+ exit 11
194
+ end
195
+
196
+ packages.sort {|a, b|
197
+ a.version <=> b.version
198
+ }.last
199
+ end
200
+ }.each {|package|
201
+ if package.is_a?(String)
202
+ path = File.dirname(File.realpath(package))
203
+ package = Package.parse(package.sub(/\.rbuild$/, ''))
204
+ else
205
+ path = "#{package.repository.path}/#{package.model.data.path}"
206
+ end
207
+
208
+ manifest = Nokogiri::XML.parse(File.read("#{path}/digest.xml"))
209
+
210
+ files = {}
211
+ manifest.xpath('//files/file').each {|e|
212
+ files[e['name']] = e.text
213
+ }
214
+
215
+ begin; package = Packo.loadPackage(path, package); rescue LoadError; end
216
+
217
+ if !package
218
+ CLI.fatal 'The package could not be instantiated'
219
+ exit 12
220
+ end
221
+
222
+ if package.parent.nil?
223
+ CLI.warn 'The package does not have a parent'
224
+ end
225
+
226
+ package.path = path
227
+
228
+ CLI.info "Building #{package}"
229
+
230
+ output = File.realpath(options[:output])
231
+
232
+ package.after :pack do |path|
233
+ FileUtils.cp path, output, preserve: true
234
+ end
235
+
236
+ if (File.read("#{package.directory}/.build") rescue nil) != package.to_s(:everything) || options[:wipe]
237
+ CLI.info "Cleaning #{package} because something changed."
238
+
239
+ clean("#{path}/#{package.name}-#{package.version}.rbuild")
240
+
241
+ package.create!
242
+
243
+ begin
244
+ File.write("#{package.directory}/.build", package.to_s(:everything))
245
+ rescue; end
246
+ end
247
+
248
+ begin
249
+ package.build {|stage|
250
+ CLI.info "Executing #{stage.name}"
251
+ }
252
+
253
+ CLI.info "Succesfully built #{package}"
254
+ rescue Exception => e
255
+ CLI.fatal "Failed to build #{package}"
256
+ CLI.fatal e.message
257
+ Packo.debug e
258
+ end
259
+ }
260
+ end
261
+
262
+ desc 'clean PACKAGE... [OPTIONS]', 'Clean packages'
263
+ method_option :repository, type: :string, aliases: '-r', desc: 'Set a specific source repository'
264
+ def clean (*packages)
265
+ packages.map {|package|
266
+ if package.end_with?('.rbuild')
267
+ package
268
+ else
269
+ require 'packo/models'
270
+
271
+ packages = Models.search(package, options[:repository])
272
+
273
+ if (multiple = packages.uniq).length > 1
274
+ CLI.fatal 'Multiple packages with the same name, be more precise.'
275
+ exit 2
276
+ end
277
+
278
+ packages.last
279
+ end
280
+ }.compact.each {|package|
281
+ if package.is_a?(String)
282
+ path = File.dirname(File.realpath(package))
283
+ package = Package.parse(package.sub(/\.rbuild$/, ''))
284
+ else
285
+ path = "#{package.repository.path}/#{package.model.data.path}"
286
+ end
287
+
288
+ begin
289
+ package = Packo.loadPackage(path, package)
290
+ package.clean!
291
+
292
+ CLI.info "Cleaned #{package.to_s(:name)}"
293
+ rescue Exception => e
294
+ CLI.fatal "Failed cleaning of #{package.to_s(:name)}"
295
+ Packo.debug e
296
+ end
297
+ }
298
+ end
299
+
300
+ desc 'digest RBUILD...', 'Digest the given rbuilds'
301
+ def digest (*files)
302
+ files.each {|file|
303
+ if !File.exists?(file)
304
+ CLI.fatal "#{file} does not exist"
305
+ exit 40
306
+ end
307
+
308
+ Dir.chdir(File.dirname(file))
309
+
310
+ begin
311
+ if File.basename(file).match(/.*?-\d/)
312
+ package = Packo.loadPackage(File.dirname(file), Package.parse(File.basename(file).sub(/\.rbuild$/, '')))
313
+ else
314
+ package = Packo.loadPackage(file)
315
+ end
316
+ rescue LoadError
317
+ CLI.fatal 'Failed to load the rbuild'
318
+ exit 41
319
+ end
320
+
321
+ if !package
322
+ CLI.fatal "Couldn't instantiate the package."
323
+ exit 42
324
+ end
325
+
326
+ package.digests = {}
327
+
328
+ package.after :fetch do |result|
329
+ package.stages.stop!
330
+
331
+ throw :halt
332
+ end
333
+
334
+ Do.cd {
335
+ package.build
336
+ }
337
+
338
+ original = Nokogiri::XML.parse(File.read('digest.xml')) {|config|
339
+ config.default_xml.noblanks
340
+ } rescue nil
341
+
342
+ builder = Nokogiri::XML::Builder.new {|xml|
343
+ xml.digest(version: '1.0') {
344
+ xml.build(version: package.version, slot: package.slot) {
345
+ xml.features package.features.to_a.map {|f| f.name}.join(' ')
346
+
347
+ xml.files {
348
+ package.distfiles.to_a.each {|(name, file)|
349
+ file ||= name
350
+
351
+ xml.file({ name: File.basename(file.path), url: file.url }, Do.digest(file.path))
352
+ } if package.distfiles
353
+ }
354
+ }
355
+
356
+ if original
357
+ original.xpath('//build').each {|build|
358
+ if build['version'] != package.version.to_s && ((build['slot'].empty? && !package.slot) || build['slot'] != package.slot.to_s)
359
+ xml.doc.root.add_child(build)
360
+ end
361
+ }
362
+ end
363
+ }
364
+ }
365
+
366
+ File.write('digest.xml', builder.to_xml(indent: 4))
367
+ }
368
+ rescue Errno::EACCES
369
+ CLI.fatal 'Try to use packo-build instead.'
370
+ end
371
+
372
+ desc 'manifest PACKAGE [OPTIONS]', 'Output the manifest of the given package'
373
+ method_option :repository, type: :string, aliases: '-r', desc: 'Set a specific source repository'
374
+ def manifest (package)
375
+ if package.end_with?('.rbuild')
376
+ if File.basename(package).match(/.*?-\d/)
377
+ package = Packo.loadPackage(File.dirname(package), Package.parse(File.basename(package).sub(/\.rbuild$/, '')))
378
+ else
379
+ package = Packo.loadPackage(package)
380
+ end
381
+ else
382
+ require 'packo/models'
383
+
384
+ tmp = Models.search(package, options[:repository])
385
+
386
+ if tmp.empty?
387
+ CLI.fatal 'Package not found'
388
+ exit 21
389
+ end
390
+
391
+ if (multiple = tmp.uniq).length > 1
392
+ CLI.fatal 'Multiple packages with the same name, be more precise.'
393
+ exit 22
394
+ end
395
+
396
+ package = Packo.loadPackage("#{tmp.last.repository.path}/#{tmp.last.model.data.path}", tmp.last)
397
+ end
398
+
399
+ if package
400
+ puts RBuild::Package::Manifest.new(package).to_s
401
+ else
402
+ CLI.fatal 'Package could not be instantiated'
403
+ exit 23
404
+ end
405
+ end
406
+
407
+ desc 'info FILE', 'Get informations about an rbuild'
408
+ def info (file)
409
+ if File.basename(file).match(/.*?-\d/)
410
+ package = Packo.loadPackage(File.dirname(file), Package.parse(File.basename(file).sub(/\.rbuild$/, '')))
411
+ else
412
+ package = Packo.loadPackage(file)
413
+ end
414
+
415
+ print package.name.bold
416
+ print "-#{package.version.to_s.red}"
417
+ print " {#{package.revision.yellow.bold}}" if package.revision > 0
418
+ print " (#{package.slot.blue.bold})" if package.slot
419
+ print " [#{package.tags.join(' ').magenta}]"
420
+ print "\n"
421
+
422
+ puts " #{'Description'.green}: #{package.description}"
423
+ puts " #{'Homepage'.green}: #{package.homepage}"
424
+ puts " #{'License'.green}: #{package.license}"
425
+ puts " #{'Maintainer'.green}: #{package.maintainer || 'nobody'}"
426
+
427
+ flavor = []
428
+ package.flavor.each {|f|
429
+ next if [:vanilla, :documentation, :headers, :debug].member?(f.name)
430
+
431
+ flavor << f
432
+ }
433
+
434
+ features = []
435
+ package.features.each {|f|
436
+ features << f
437
+ }
438
+
439
+ length = (flavor + features).map {|f|
440
+ f.name.length
441
+ }.max
442
+
443
+ if flavor.length > 0
444
+ print " #{'Flavor'.green}: "
445
+
446
+ flavor.each {|element|
447
+ if element.enabled
448
+ print "#{element.name.to_s.white.bold}#{System.env[:NO_COLORS] ? '!' : ''}"
449
+ else
450
+ print element.name.to_s.black.bold
451
+ end
452
+
453
+ print "#{' ' * (4 + length - element.name.length + (System.env[:NO_COLORS] && !element.enabled? ? 1 : 0))}#{element.description || '...'}"
454
+
455
+ print "\n "
456
+ }
457
+
458
+ print "\r" if features.length > 0
459
+ end
460
+
461
+ if features.length > 0
462
+ print " #{'Features'.green}: "
463
+
464
+ features.each {|feature|
465
+ if feature.enabled
466
+ print "#{feature.name.to_s.white.bold}#{System.env[:NO_COLORS] ? '!' : ''}"
467
+ else
468
+ print feature.name.to_s.black.bold
469
+ end
470
+
471
+ print "#{' ' * (4 + length - feature.name.length + (System.env[:NO_COLORS] && !feature.enabled? ? 1 : 0))}#{feature.description || '...'}"
472
+
473
+ print "\n "
474
+ }
475
+ end
476
+
477
+ print "\n"
478
+ end
479
+
480
+ def initialize (*args)
481
+ FileUtils.mkpath(System.env[:TMP])
482
+ File.umask 022
483
+
484
+ super(*args)
485
+ end
486
+ end
487
+
488
+ end; end