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,269 @@
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 'tempfile'
21
+ require 'tmpdir'
22
+ require 'pathname'
23
+
24
+ require 'packo/profile'
25
+ require 'packo/flags'
26
+
27
+ module Packo
28
+
29
+ class Environment < Hash
30
+ @@default = {
31
+ ARCH: nil,
32
+ KERNEL: nil,
33
+ LIBC: nil,
34
+ COMPILER: nil,
35
+
36
+ CFLAGS: '-Os -pipe',
37
+ CXXFLAGS: '-Os -pipe',
38
+ CPPFLAGS: '',
39
+ LDFLAGS: '-Wl,-O1 -Wl,--as-needed',
40
+ MAKE_JOBS: 1,
41
+
42
+ FLAVOR: 'vanilla',
43
+ FEATURES: '',
44
+ USE: '',
45
+
46
+ PROFILES: '',
47
+
48
+ FETCHER: 'wget -c -O "#{output}" "#{source}"',
49
+
50
+ NO_COLORS: false,
51
+ DEBUG: nil,
52
+ VERBOSE: false,
53
+ SECURE: true,
54
+
55
+ TMP: "#{Dir.tmpdir}/packo-#{ENV['USER'] || Process.euid}"
56
+ }
57
+
58
+ if Process.euid == 0 && ENV['USER'] == 'root'
59
+ @@default.merge!(
60
+ CONFIG_PATH: '/etc/packo',
61
+ INSTALL_PATH: '/',
62
+
63
+ DATABASE: 'sqlite:///var/lib/packo/db',
64
+
65
+ REPOSITORIES: '/var/lib/packo/repositories',
66
+ SELECTORS: '/var/lib/packo/selectors',
67
+ )
68
+ else
69
+ @@default.merge!(
70
+ CONFIG_PATH: "#{ENV['HOME']}/.packo",
71
+ INSTALL_PATH: "#{ENV['HOME']}/.packo/disk",
72
+
73
+ DATABASE: "sqlite://#{ENV['HOME']}/.packo/db",
74
+
75
+ REPOSITORIES: "#{ENV['HOME']}/.packo/repositories",
76
+ SELECTORS: "#{ENV['HOME']}/.packo/selectors",
77
+ )
78
+ end
79
+
80
+ @@callbacks = {
81
+ COMPILER: lambda {|value|
82
+ self[:CPP] = 'cpp'
83
+ self[:AS] = 'as'
84
+ self[:AR] = 'ar'
85
+ self[:LD] = 'ld'
86
+ self[:RANLIB] = 'ranlib'
87
+
88
+ case value
89
+ when 'gcc'
90
+ self[:CC] = 'gcc'
91
+ self[:CXX] = 'g++'
92
+
93
+ when 'clang'
94
+ self[:CC] = 'clang'
95
+ self[:CXX] = 'clang++'
96
+
97
+ else
98
+ raise ArgumentError.new 'I do not know that compiler :<' if value
99
+ end
100
+ }
101
+ }
102
+
103
+ def self.[] (name, nodefault=false)
104
+ value = ENV["PACKO_#{name}"] || ENV[name.to_s] || (nodefault ? nil : @@default[name.to_sym]) or return
105
+
106
+ return value unless value.is_a?(String)
107
+
108
+ return nil if value.strip.empty?
109
+
110
+ return case value.strip
111
+ when 'false'; false
112
+ when 'true'; true
113
+ else; value
114
+ end
115
+ end
116
+
117
+ def self.[]= (name, value)
118
+ ENV["PACKO_#{name}"] = value.to_s rescue ''
119
+ end
120
+
121
+ def self.each (limit=true)
122
+ variables = (@@default.keys + (ENV.map {|(key, value)|
123
+ if limit
124
+ key.sub(/^PACKO_/, '').to_sym if key.start_with?('PACKO_')
125
+ else
126
+ key.start_with?('PACKO_') ?
127
+ key.sub(/^PACKO_/, '').to_sym :
128
+ key.to_sym
129
+ end
130
+ }.compact)).uniq
131
+
132
+ if variables.member?(:FLAVORS)
133
+ variables.delete(:FLAVORS)
134
+ variables << :FLAVOR
135
+
136
+ Environment[:FLAVOR] = Environment[:FLAVORS]
137
+ end
138
+
139
+ variables.each {|name|
140
+ yield name, Environment[name]
141
+ }
142
+ end
143
+
144
+ def self.clone
145
+ result = {}
146
+
147
+ Environment.each {|name, value|
148
+ result[name.to_s] = value
149
+ }
150
+
151
+ result
152
+ end
153
+
154
+ def self.sandbox (box)
155
+ old = Hash[ENV]
156
+
157
+ box.each {|key, value|
158
+ ENV[key.to_s] = value.to_s
159
+ }
160
+
161
+ begin
162
+ result = yield
163
+ rescue Exception => e
164
+ result = e
165
+ end
166
+
167
+ box.each {|key, value|
168
+ ENV.delete(key.to_s)
169
+ }
170
+
171
+ old.each {|key, value|
172
+ ENV[key] = value
173
+ }
174
+
175
+ if result.is_a?(Exception)
176
+ raise result
177
+ else
178
+ return result
179
+ end
180
+ end
181
+
182
+ attr_reader :package, :profiles
183
+
184
+ def initialize (package=nil, noenv=false)
185
+ @package = package
186
+ @profiles = []
187
+
188
+ @profiles << Profile.path(Environment[:CONFIG_PATH])
189
+ @profiles << Profile.path("#{ENV['HOME']}/.packo")
190
+ @profiles << Profile.path('/var/lib/packo')
191
+
192
+ Environment[:PROFILES].split(/\s*;\s*/).each {|profile|
193
+ @profiles << Profile.path(profile)
194
+ } if Environment[:PROFILES]
195
+
196
+ if File.readable?("#{ENV['HOME']}/.packo/profiles")
197
+ files = File.read("#{ENV['HOME']}/.packo/profiles").split("\n")
198
+ elsif File.readable?('/etc/packo/profiles')
199
+ files << File.read('/etc/packo/profiles').split("\n")
200
+ end
201
+
202
+ files.each {|profile|
203
+ @profiles << Profile.path(profile)
204
+ } if files
205
+
206
+ @profiles.compact!
207
+
208
+ apply!(noenv)
209
+
210
+ yield self if block_given?
211
+ end
212
+
213
+ def apply! (noenv=false)
214
+ self.clear
215
+
216
+ @profiles.each {|profile|
217
+ profile.apply!(self, @package)
218
+ }
219
+
220
+ if noenv
221
+ @@default.each {|key, value|
222
+ self[key] = value unless self[key]
223
+ }
224
+ else
225
+ Environment.each(false) {|key, value|
226
+ next if value.nil?
227
+
228
+ # This is an array, not a call to self.[]
229
+ if [:FEATURES].member?(key)
230
+ (self[key] ||= '') << " #{value}"
231
+ else
232
+ self[key] = value unless self[key] && value == @@default[key] && !Environment[key, true]
233
+ end
234
+ }
235
+ end
236
+
237
+ self.each {|key, value|
238
+ if key.to_s.end_with?('FLAGS')
239
+ self[key] = Flags.parse(value.to_s)
240
+ elsif key.to_s.end_with?('PATH')
241
+ self[key] = Pathname.new(value.to_s)
242
+ end
243
+ }
244
+ end
245
+
246
+ def [] (name)
247
+ super(name.to_sym)
248
+ end
249
+
250
+ def []= (name, value)
251
+ self.instance_exec(value, &@@callbacks[name.to_sym]) if @@callbacks[name.to_sym]
252
+
253
+ if name.to_s.end_with?('FLAGS')
254
+ value = Flags.parse(value.to_s)
255
+ elsif name.to_s.end_with?('PATH')
256
+ value = Pathname.new(value.to_s)
257
+ end
258
+
259
+ super(name.to_sym, value)
260
+ end
261
+
262
+ def sandbox (changes={}, &block)
263
+ Environment.sandbox(self.merge({
264
+ ARCH: Host.new(self).arch
265
+ }.merge(changes)), &block)
266
+ end
267
+ end
268
+
269
+ end
@@ -0,0 +1,70 @@
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 'ostruct'
21
+
22
+ class Object
23
+ def numeric?
24
+ true if Float(self) rescue false
25
+ end
26
+ end
27
+
28
+ module Kernel
29
+ def suppress_warnings
30
+ tmp, $VERBOSE = $VERBOSE, nil
31
+
32
+ result = yield
33
+
34
+ $VERBOSE = tmp
35
+
36
+ return result
37
+ end
38
+ end
39
+
40
+ class File
41
+ def self.write (path, data, mode=nil)
42
+ open(path, 'wb') {|f|
43
+ f.write data
44
+ f.chmod mode if mode
45
+ }
46
+ end
47
+
48
+ def self.append (path, data, mode=nil)
49
+ open(path, 'ab') {|f|
50
+ f.write data
51
+ f.chmod mode if mode
52
+ }
53
+ end
54
+ end
55
+
56
+ class String
57
+ def interpolate (on)
58
+ on.instance_eval("%{#{self}}") rescue self
59
+ end
60
+
61
+ def === (value)
62
+ value.is_a?(Packo::Host) ?
63
+ value == self :
64
+ super(value)
65
+ end
66
+ end
67
+
68
+ class OpenStruct
69
+ alias to_hash marshal_dump
70
+ end
@@ -0,0 +1,64 @@
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
21
+
22
+ class Flags < Array
23
+ def self.parse (string)
24
+ Flags.new(*string.to_s.split(/\s+/))
25
+ end
26
+
27
+ def initialize (*flags)
28
+ self.insert(-1, *flags)
29
+ end
30
+
31
+ def push (*values)
32
+ values.each {|value|
33
+ super(value.to_s.strip)
34
+ }
35
+
36
+ self
37
+ end
38
+
39
+ alias << push
40
+
41
+ def delete (*values)
42
+ values.each {|value|
43
+ super(value)
44
+ }
45
+
46
+ self
47
+ end
48
+
49
+ def replace (from, to)
50
+ tmp, _ = self.dup, self.clear
51
+
52
+ self.insert(-1, *tmp.map {|value|
53
+ value.match(from) ? to : value
54
+ })
55
+
56
+ self
57
+ end
58
+
59
+ def to_s
60
+ self.join(' ')
61
+ end
62
+ end
63
+
64
+ end
data/lib/packo/host.rb ADDED
@@ -0,0 +1,121 @@
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/environment'
21
+
22
+ module Packo
23
+
24
+ class Host
25
+ def self.parse (text)
26
+ matches = text.match(/^([^-]+)(-([^-]+))?-([^-]+)(-([^-]+))?$/) or return
27
+
28
+ Host.new(
29
+ ARCH: matches[1],
30
+ VENDOR: matches[3],
31
+ KERNEL: matches[4],
32
+ MISC: matches[6]
33
+ ) rescue nil
34
+ end
35
+
36
+ def self.arch (value=System.env![:ARCH])
37
+ case value
38
+ when 'core2', 'k8'; 'x86_64'
39
+ when 'x86'; 'i686'
40
+
41
+ when 'i386', 'i486', 'i586', 'i686',
42
+ 'amd64', 'x86_64'
43
+ ; value
44
+
45
+ else; raise ArgumentError.new('Architecture not supported')
46
+ end
47
+ end
48
+
49
+ def self.vendor (value=System.env![:VENDOR])
50
+ case value
51
+ when 'pc'; value
52
+
53
+ else; 'unknown'
54
+ end
55
+ end
56
+
57
+ def self.kernel (value=System.env![:KERNEL])
58
+ case value
59
+ when 'windows'; 'cygwin'
60
+ when 'mac'; 'darwin'
61
+ when 'linux'; 'linux'
62
+
63
+ else; raise ArgumentError.new('Kernel not supported')
64
+ end
65
+ end
66
+
67
+ def self.misc (value=System.env![:MISC])
68
+ case value
69
+ when 'gnu'; value
70
+ end
71
+ end
72
+
73
+ attr_reader :arch, :vendor, :kernel, :misc
74
+
75
+ def initialize (data)
76
+ self.arch = data[:ARCH]
77
+ self.vendor = data[:VENDOR]
78
+ self.kernel = data[:KERNEL]
79
+ self.misc = data[:MISC]
80
+
81
+ if !self.misc && data[:LIBC] == 'glibc' && (self.kernel == 'linux')
82
+ self.misc = 'gnu'
83
+ end
84
+
85
+ if self.vendor == 'unknown' && ['x86_64', 'i386', 'i486', 'i586', 'i686'].member?(self.arch)
86
+ self.vendor = 'pc'
87
+ end
88
+ end
89
+
90
+ def arch= (value)
91
+ @arch = Host.arch(value)
92
+ end
93
+
94
+ def vendor= (value)
95
+ @vendor = Host.vendor(value)
96
+ end
97
+
98
+ def kernel= (value)
99
+ @kernel = Host.kernel(value)
100
+ end
101
+
102
+ def misc= (value)
103
+ @misc = Host.misc(value)
104
+ end
105
+
106
+ def == (value)
107
+ if value.is_a?(Host)
108
+ self.to_s == value.to_s
109
+ else
110
+ !!self.to_s.match(Regexp.new('^' + Regexp.escape(value.to_s).gsub(/\\\*/, '.*?').gsub(/\\\?/, '.') + '$', 'i'))
111
+ end
112
+ end
113
+
114
+ alias === ==
115
+
116
+ def to_s
117
+ "#{arch}#{"-#{vendor}" if vendor}-#{kernel}#{"-#{misc}" if misc}"
118
+ end
119
+ end
120
+
121
+ end