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,169 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of packo.
5
+ #
6
+ # packo is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # packo is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with packo. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'nokogiri'
21
+ require 'base64'
22
+
23
+ require 'packo'
24
+
25
+ module Packo; module RBuild; class Package < Packo::Package
26
+
27
+ class Manifest
28
+ def self.parse (text)
29
+ dom = Nokogiri::XML.parse(text)
30
+
31
+ Manifest.new(OpenStruct.new(
32
+ maintainer: dom.root['maintainer'],
33
+
34
+ tags: Packo::Package::Tags.parse(dom.xpath('//package/tags').first.text),
35
+ name: dom.xpath('//package/name').first.text,
36
+ version: Versionomy.parse(dom.xpath('//package/version').first.text),
37
+ slot: dom.xpath('//package/slot').first.text,
38
+
39
+ exports: Marshal.load(Base64.decode64(dom.xpath('//package/exports').first.text)),
40
+
41
+ description: dom.xpath('//package/description').first.text,
42
+ homepage: dom.xpath('//package/homepage').first.text.split(/\s+/),
43
+ license: dom.xpath('//package/license').first.text.split(/\s+/),
44
+
45
+ flavor: Packo::Package::Flavor.parse(dom.xpath('//package/flavor').first.text || ''),
46
+ features: Packo::Package::Features.parse(dom.xpath('//package/features').first.text || ''),
47
+
48
+ environment: Hash[dom.xpath('//package/environment/variable').map {|env|
49
+ [env['name'], env.text]
50
+ }],
51
+
52
+ dependencies: dom.xpath('//dependencies/dependency').map {|dependency|
53
+ Package::Dependency.parse("#{dependency.text}#{['', '!', '!!'][['both', 'build', 'runtime'].index(dependency['type'])]}")
54
+ },
55
+
56
+ blockers: dom.xpath('//blockers/blocker').map {|blocker|
57
+ Package::Blocker.parse("#{blocker.text}#{['', '!', '!!'][['both', 'build', 'runtime'].index(dependency['type'])]}")
58
+ },
59
+
60
+ selector: dom.xpath('//selectors/selector').map {|selector|
61
+ Hash[
62
+ name: selector['name'],
63
+ description: selector['description'],
64
+ path: selector.text
65
+ ]
66
+ }
67
+ ))
68
+ end
69
+
70
+ def self.open (path)
71
+ Manifest.parse(File.read(path))
72
+ end
73
+
74
+ attr_reader :package, :dependencies, :blockers, :selectors
75
+
76
+ def initialize (what)
77
+ @package = OpenStruct.new(
78
+ maintainer: what.maintainer,
79
+
80
+ tags: what.tags,
81
+ name: what.name,
82
+ version: what.version,
83
+ slot: what.slot,
84
+
85
+ exports: what.exports,
86
+
87
+ description: what.description,
88
+ homepage: [what.homepage].flatten.compact.join(' '),
89
+ license: [what.license].flatten.compact.join(' '),
90
+
91
+ flavor: what.flavor,
92
+ features: what.features,
93
+
94
+ environment: what.environment.reject {|name, value|
95
+ [:DATABASE, :FLAVORS, :PROFILE, :CONFIG_FILE, :CONFIG_PATH,
96
+ :CONFIG_MODULES, :REPOSITORIES, :SELECTORS, :FETCHER,
97
+ :NO_COLORS, :DEBUG, :VERBOSE, :TMP, :SECURE
98
+ ].member?(name.to_sym)
99
+ }
100
+ )
101
+
102
+ @dependencies = what.dependencies
103
+ @blockers = what.blockers
104
+ @selectors = [what.selector].flatten.compact.map {|selector| OpenStruct.new(selector)}
105
+
106
+ if (what.filesystem.selectors rescue false)
107
+ what.filesystem.selectors.each {|name, file|
108
+ matches = file.content.match(/^#\s*(.*?):\s*(.*)([\n\s]*)?\z/) or next
109
+
110
+ @selectors << OpenStruct.new(name: matches[1], description: matches[2], path: name)
111
+ }
112
+ end
113
+
114
+ @builder = Nokogiri::XML::Builder.new {|xml|
115
+ xml.manifest(version: '1.0') {
116
+ xml.package(maintainer: self.package.maintainer) {
117
+ xml.tags self.package.tags
118
+ xml.name self.package.name
119
+ xml.version self.package.version
120
+ xml.slot self.package.slot
121
+ xml.revision self.package.revision
122
+
123
+ xml.description self.package.description
124
+ xml.homepage self.package.homepage
125
+ xml.license self.package.license
126
+
127
+ xml.flavor self.package.flavor
128
+ xml.features self.package.features
129
+
130
+ xml.environment {
131
+ self.package.environment.each {|name, value|
132
+ xml.variable({ name: name }, value)
133
+ }
134
+ }
135
+
136
+ xml.exports Base64.encode64(Marshal.dump(self.package.exports))
137
+ }
138
+
139
+ xml.dependencies {
140
+ self.dependencies.each {|dependency|
141
+ xml.dependency({ type: dependency.type }, dependency.to_s)
142
+ }
143
+ }
144
+
145
+ xml.blockers {
146
+ self.blockers.each {|blocker|
147
+ xml.blocker({ type: blocker.type }, blocker.to_s)
148
+ }
149
+ }
150
+
151
+ xml.selectors {
152
+ self.selectors.each {|selector|
153
+ xml.selector({ name: selector.name, description: selector.description }, selector.path)
154
+ }
155
+ }
156
+ }
157
+ }
158
+ end
159
+
160
+ def save (to, options={})
161
+ File.write(to, self.to_s(options))
162
+ end
163
+
164
+ def to_s (options={})
165
+ @builder.to_xml({ indent: 4 }.merge(options))
166
+ end
167
+ end
168
+
169
+ end; end; end
@@ -0,0 +1,171 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of packo.
5
+ #
6
+ # packo is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # packo is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with packo. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ require 'packo/rbuild/stages/stage'
21
+ require 'packo/rbuild/stages/callbacks'
22
+
23
+ module Packo; module RBuild
24
+
25
+ class Stages
26
+ module Callable
27
+ def before (name, data=nil, &block)
28
+ self.package.stages.register(:before, name, block, { binding: self }.merge(data || {}))
29
+ end
30
+
31
+ def after (name, data=nil, &block)
32
+ self.package.stages.register(:after, name, block, { binding: self }.merge(data || {}))
33
+ end
34
+
35
+ def avoid (chain, name, known=nil)
36
+ self.package.stages.unregister(chain, name, known)
37
+ end
38
+ end
39
+
40
+ attr_reader :package, :stages, :callbacks
41
+
42
+ def initialize (package)
43
+ @package = package
44
+
45
+ @stages = []
46
+ @callbacks = {}
47
+ end
48
+
49
+ def add (name, method, options={})
50
+ @stages.delete_if {|stage|
51
+ stage.name == name
52
+ }
53
+
54
+ @stages << Stage.new(name, method, options)
55
+
56
+ @sorted = false
57
+ end
58
+
59
+ def delete (name, method=nil)
60
+ @stages.delete_if {|stage|
61
+ stage.name == name && (!method || stage.method == method)
62
+ }
63
+
64
+ @sorted = false
65
+ end
66
+
67
+ # Ugly incomprensibile shit ahead. It's dangerous to go alone! Take this! <BS>
68
+ #
69
+ # In short it tries to sort stuff as it wanted to be placed depending on stage's options
70
+ def sort! (strict=false)
71
+ return if @sorted
72
+
73
+ funcs = {
74
+ atom: lambda {
75
+ { stricts: [], normals: [] }
76
+ },
77
+
78
+ leaf: lambda {
79
+ Hash[
80
+ after: funcs[:atom].call,
81
+ before: funcs[:atom].call,
82
+ at: funcs[:atom].call,
83
+ stage: nil
84
+ ]
85
+ },
86
+
87
+ type: lambda {|stage|
88
+ stage.options[:strict] ? :stricts : :normals
89
+ },
90
+
91
+ plain: lambda {|pi|
92
+ pi.sort {|a, b|
93
+ pr = (a[:stage].options[:priority] || 0) <=> (b[:stage].options[:priority] || 0)
94
+ pr.zero? ? a[:stage].name.to_s.downcase <=> b[:stage].name.to_s.downcase : pr
95
+ }.map {|l|
96
+ funcs[:flat].call(l)
97
+ }.flatten
98
+ },
99
+
100
+ flat: lambda {|leaf|
101
+ funcs[:plain].call(leaf[:after][:normals]) + funcs[:plain].call(leaf[:after][:stricts]) +
102
+ (leaf[:stage] ? [leaf[:stage]] : (funcs[:plain].call(leaf[:at][:stricts]) + funcs[:plain].call(leaf[:at][:normals]))) +
103
+ funcs[:plain].call(leaf[:before][:stricts]) + funcs[:plain].call(leaf[:before][:normals])
104
+ }
105
+ }
106
+
107
+ tree = { beginning: funcs[:leaf].call, end: funcs[:leaf].call }
108
+
109
+ remained = @stages.dup
110
+ prev_rem = @stages.size
111
+
112
+ begin
113
+ prev_rem = remained.size
114
+
115
+ remained.dup.each {|stage|
116
+ place = (if tree[stage.options[:after]]
117
+ [stage.options[:after], :before, funcs[:type].call(stage)]
118
+ elsif tree[stage.options[:before]]
119
+ [stage.options[:before], :after, funcs[:type].call(stage)]
120
+ elsif [:beginning, :end].include?(stage.options[:at])
121
+ [stage.options[:at], :at, funcs[:type].call(stage)]
122
+ else
123
+ nil
124
+ end)
125
+
126
+ next unless place
127
+
128
+ remained.delete(stage)
129
+
130
+ leaf = funcs[:leaf].call
131
+ leaf[:stage] = stage
132
+
133
+ tree[place[0]][place[1]][place[2]] << leaf
134
+
135
+ tree[stage.name.to_sym] = leaf
136
+ }
137
+ end while prev_rem != remained.size
138
+
139
+ tree[:beginning][:after] = tree[:end][:before] = funcs[:atom].call
140
+
141
+ @stages = funcs[:flat].call(tree[:beginning]) + funcs[:flat].call(tree[:end])
142
+ @sorted = true
143
+ end
144
+
145
+ def stop!; @stopped = true; end
146
+ def restart!; @stopped = false; end
147
+
148
+ def each (&block)
149
+ self.sort!
150
+
151
+ @stages.each {|stage|
152
+ block.call stage
153
+
154
+ break if @stopped
155
+ }
156
+ end
157
+
158
+ def register (chain, name, callback, data={})
159
+ (@callbacks[name.to_sym] ||= Callbacks.new(name.to_sym)).register(chain, callback, data)
160
+ end
161
+
162
+ def unregister (chain, name, known=nil)
163
+ (@callbacks[name.to_sym] ||= Callbacks.new(name.to_sym)).unregister(chain, known)
164
+ end
165
+
166
+ def callbacks (name)
167
+ @callbacks[name.to_sym] ||= Callbacks.new(name.to_sym)
168
+ end
169
+ end
170
+
171
+ end; end
@@ -0,0 +1,96 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of packo.
5
+ #
6
+ # packo is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # packo is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with packo. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module Packo; module RBuild; class Stages
21
+
22
+ class Callbacks
23
+ Chains = [:before, :after]
24
+
25
+ class Callback
26
+ attr_accessor :binding
27
+
28
+ attr_reader :name, :priority, :position
29
+
30
+ def initialize (callback, data)
31
+ @callback = callback
32
+ @priority = data[:priority] || 0
33
+ @binding = data[:binding] || binding
34
+ @position = data[:position] || 0
35
+ @name = data[:name]
36
+ end
37
+
38
+ def call (*args)
39
+ if binding
40
+ binding.instance_exec(*args, &@callback)
41
+ else
42
+ @callback.call(*args)
43
+ end
44
+ end
45
+ end
46
+
47
+ attr_reader :name
48
+
49
+ def initialize (name)
50
+ @name = name
51
+ @callbacks = Hash[before: [], after: []]
52
+ @position = 0
53
+ end
54
+
55
+ def register (chain, callback, data)
56
+ @callbacks[Chains.member?(chain) ? chain : :before] << Callback.new(callback, { position: @position += 1 }.merge(data))
57
+ end
58
+
59
+ def unregister (chain, name=nil)
60
+ @callbacks[Chains.member?(chain) ? chain : :before].delete_if {|callback|
61
+ callback.name == name || name.nil?
62
+ }
63
+ end
64
+
65
+ def sort!
66
+ Chains.each {|chain|
67
+ @callbacks[chain].sort! {|a, b|
68
+ if a.priority == b.priority
69
+ a.position <=> b.position
70
+ else
71
+ a.priority <=> b.priority
72
+ end
73
+ }
74
+ }
75
+ end
76
+
77
+ def do (*args)
78
+ self.sort!
79
+
80
+ catch(:halt) do
81
+ @callbacks[:before].each {|c|
82
+ c.call(*args)
83
+ }
84
+
85
+ result = yield *args if block_given?
86
+
87
+ @callbacks[:after].each {|c|
88
+ c.call(result, *args)
89
+ }
90
+
91
+ result
92
+ end
93
+ end
94
+ end
95
+
96
+ end; end; end
@@ -0,0 +1,50 @@
1
+ #--
2
+ # Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
3
+ #
4
+ # This file is part of packo.
5
+ #
6
+ # packo is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # packo is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with packo. If not, see <http://www.gnu.org/licenses/>.
18
+ #++
19
+
20
+ module Packo; module RBuild; class Stages;
21
+
22
+ class Stage
23
+ attr_reader :name, :options, :method
24
+
25
+ def initialize (name, method, options)
26
+ @name = name.to_sym
27
+ @method = method
28
+ @options = options
29
+
30
+ if (@options[:at] || @options[:after] == :beginning || @options[:before] == :ending) && @options[:strict].nil?
31
+ @options[:strict] = true
32
+ end
33
+
34
+ @options[:priority] ||= 0
35
+ end
36
+
37
+ def call (*args)
38
+ @method.call(*args)
39
+ end
40
+
41
+ def == (value)
42
+ @name == value || @method == value
43
+ end
44
+
45
+ def inspect
46
+ "#<Stage: #{name} (#{@options.inspect})>"
47
+ end
48
+ end
49
+
50
+ end; end; end