packo 0.0.1.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
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