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,23 @@
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/modules/misc/unpacking/tar'
21
+ require 'packo/rbuild/modules/misc/unpacking/zip'
22
+ require 'packo/rbuild/modules/misc/unpacking/lzma'
23
+ require 'packo/rbuild/modules/misc/unpacking/xz'
@@ -0,0 +1,34 @@
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; module Modules; module Misc
21
+
22
+ Unpacker.register /\.lzma$/ do |path, to|
23
+ Packo.sh 'lzma', '-dfk', path
24
+
25
+ path.sub!(/\.lzma$/, '')
26
+
27
+ if to
28
+ Do.mv(path, (path = to))
29
+ end
30
+
31
+ path
32
+ end
33
+
34
+ end; end; end; end
@@ -0,0 +1,35 @@
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; module Modules; module Misc
21
+
22
+ Unpacker.register /\.((tar\.(bz2|gz|xz|lzma))|tgz)$/ do |path, to|
23
+ options = [case File.extname(path)
24
+ when '.xz'; '--xz'
25
+ when '.lzma'; '--lzma'
26
+ end].flatten.compact
27
+
28
+ if to
29
+ options << '-C' << to
30
+ end
31
+
32
+ Packo.sh 'tar', 'xf', path, *options, '-k'
33
+ end
34
+
35
+ end; end; end; end
@@ -0,0 +1,34 @@
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; module Modules; module Misc
21
+
22
+ Unpacker.register /\.xz$/ do |path, to|
23
+ Packo.sh 'xz', '-dfk', path
24
+
25
+ path.sub!(/\.xz$/, '')
26
+
27
+ if to
28
+ Do.mv(path, (path = to))
29
+ end
30
+
31
+ path
32
+ end
33
+
34
+ end; end; end; end
@@ -0,0 +1,26 @@
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; module Modules; module Misc
21
+
22
+ Unpacker.register /\.zip$/ do |path, to|
23
+ Packo.sh 'unzip', '-qq', *(to ? ['-d', to] : []), path
24
+ end
25
+
26
+ end; end; end; end
@@ -0,0 +1,20 @@
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/modules/packaging/pko'
@@ -0,0 +1,78 @@
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; module Modules; module Packaging
21
+
22
+ class PKO < Module
23
+ def self.pack (name, *files)
24
+ Packo.sh 'tar', 'cJf', name, *files, '--preserve', silent: true
25
+ end
26
+
27
+ def self.unpack (name, to)
28
+ FileUtils.mkpath(to) rescue nil
29
+
30
+ Packo.sh 'tar', 'xJf', name, '-C', to, '--preserve', silent: true
31
+ end
32
+
33
+ def initialize (package)
34
+ super(package)
35
+
36
+ package.stages.add :pack, self.method(:pack), at: :end, strict: true
37
+ end
38
+
39
+ def finalize
40
+ package.stages.delete :pack, self.method(:pack)
41
+ end
42
+
43
+ def pack
44
+ package.stages.callbacks(:pack).do {
45
+ path = "#{package.to_s(:package)}.pko"
46
+
47
+ Dir.chdir package.directory
48
+
49
+ FileUtils.mkpath "#{package.directory}/pre"
50
+
51
+ package.filesystem.pre.each {|name, file|
52
+ File.write("pre/#{name}", file.content, 0777)
53
+ }
54
+
55
+ FileUtils.mkpath "#{package.directory}/post"
56
+ package.filesystem.post.each {|name, file|
57
+ File.write("post/#{name}", file.content, 0777)
58
+ }
59
+
60
+ FileUtils.mkpath "#{package.directory}/selectors"
61
+ package.filesystem.selectors.each {|name, file|
62
+ File.write("selectors/#{name}", file.content, 0777)
63
+ }
64
+
65
+ Package::Manifest.new(package).save('manifest.xml')
66
+
67
+ package.stages.callbacks(:pack!).do {
68
+ Do.clean(package.distdir)
69
+
70
+ PKO.pack(path, 'dist/', 'pre/', 'post/', 'selectors/', 'manifest.xml')
71
+ }
72
+
73
+ path
74
+ }
75
+ end
76
+ end
77
+
78
+ end; end; end; end
@@ -0,0 +1,281 @@
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 'fffs'
21
+ require 'find'
22
+
23
+ require 'packo/package'
24
+ require 'packo/package/dependencies'
25
+ require 'packo/package/blockers'
26
+
27
+ require 'packo/rbuild/stages'
28
+ require 'packo/rbuild/features'
29
+ require 'packo/rbuild/flavor'
30
+ require 'packo/rbuild/package/manifest'
31
+
32
+ module Packo; module RBuild
33
+
34
+ class Package < Packo::Package
35
+ def self.last
36
+ @@last
37
+ end
38
+
39
+ include Stages::Callable
40
+
41
+ def self.define (name, version=nil, slot=nil, revision=nil, &block)
42
+ Package.new(name, version, slot, revision, &block)
43
+ end
44
+
45
+ attr_reader :parent, :do, :modules, :dependencies, :blockers, :stages, :filesystem
46
+
47
+ def initialize (name, version=nil, slot=nil, revision=nil, &block)
48
+ super(
49
+ name: name,
50
+ version: version,
51
+ slot: slot,
52
+ revision: revision
53
+ )
54
+
55
+ @filesystem = FFFS::FileSystem.new
56
+
57
+ ['pre', 'post', 'selectors', 'patches', 'files'].each {|dir|
58
+ @filesystem << FFFS::Directory.new(dir)
59
+ }
60
+
61
+ if !self.version
62
+ @block = block
63
+
64
+ return @@last = self
65
+ end
66
+
67
+ @modules = []
68
+ @stages = Stages.new(self)
69
+ @do = Do.new(self)
70
+ @dependencies = Dependencies.new(self)
71
+ @blockers = Blockers.new(self)
72
+ @features = Features.new(self)
73
+ @flavor = Flavor.new(self)
74
+
75
+ @stages.add :dependencies, self.method(:dependencies_check), at: :beginning
76
+ @stages.add :blockers, self.method(:blockers_check), at: :beginning
77
+
78
+ behavior Behaviors::Default
79
+ use Modules::Packaging::PKO
80
+
81
+ if (@parent = Package.last)
82
+ self.instance_exec(self, &@parent.instance_eval('@block'))
83
+ end
84
+
85
+ flavor {
86
+ vanilla {
87
+ description 'Apply only the patches needed to build succesfully the package'
88
+
89
+ needs :not, :documentation, :headers, :debug
90
+ }
91
+
92
+ documentation {
93
+ description 'Add documentation to the package'
94
+
95
+ before :pack, name: :documentation do
96
+ next if flavor.vanilla?
97
+
98
+ if !enabled?
99
+ Find.find(distdir) {|file|
100
+ if ['man', 'info', 'doc'].member?(File.basename(file)) && File.directory?(file)
101
+ FileUtils.rm_rf(file, secure: true) rescue nil
102
+ end
103
+ }
104
+ end
105
+ end
106
+ }
107
+
108
+ headers {
109
+ description 'Add headers to the package'
110
+
111
+ before :pack, name: :headers do
112
+ next if flavor.vanilla?
113
+
114
+ if !enabled?
115
+ Find.find(distdir) {|file|
116
+ if ['include', 'headers'].member?(File.basename(file)) && File.directory?(file)
117
+ FileUtils.rm_rf(file, secure: true) rescue nil
118
+ end
119
+ }
120
+ end
121
+ end
122
+ }
123
+
124
+ debug {
125
+ description 'Make a debug build'
126
+ }
127
+ }
128
+
129
+ self.directory = Pathname.new("#{package.env[:TMP]}/#{tags.to_s(true)}/#{name}/#{slot}/#{version}").cleanpath.to_s
130
+ self.workdir = "#{package.directory}/work"
131
+ self.distdir = "#{package.directory}/dist"
132
+ self.tempdir = "#{package.directory}/temp"
133
+ self.fetchdir = System.env[:FETCH_PATH] || self.tempdir
134
+
135
+ stages.callbacks(:initialize).do(self) {
136
+ self.instance_exec(self, &block) if block
137
+ }
138
+
139
+ self.envify!
140
+ self.export! :arch, :kernel, :compiler, :libc
141
+
142
+ flavor.dup.each {|element|
143
+ next unless element.enabled?
144
+
145
+ element.needs.dup.each {|need|
146
+ if tmp = need.match(/^-(.+)$/)
147
+ if element.get(tmp[1]).enabled?
148
+ element.disable!
149
+
150
+ if System.env[:VERBOSE]
151
+ require 'packo/cli'
152
+ CLI.warn "Flavor #{element} can't be enabled with #{tmp[1]}, disabling."
153
+ end
154
+ end
155
+ elsif flavor.get(need).disabled?
156
+ element.disable!
157
+
158
+ if System.env[:VERBOSE]
159
+ require 'packo/cli'
160
+ CLI.warn "Flavor #{element} needs #{need}, disabling"
161
+ end
162
+ end
163
+ }
164
+ }
165
+
166
+ features.dup.each {|feature|
167
+ next unless feature.enabled?
168
+
169
+ feature.needs.dup.each {|need|
170
+ if tmp = need.match(/^-(.+)$/)
171
+ if features.get(tmp[1]).enabled?
172
+ feature.disable!
173
+
174
+ if System.env[:VERBOSE]
175
+ require 'packo/cli'
176
+ CLI.warn "Feature #{feature} can't be enabled with #{tmp[1]}, disabling."
177
+ end
178
+ end
179
+ elsif features.get(need).disabled?
180
+ feature.disable!
181
+
182
+ if System.env[:VERBOSE]
183
+ require 'packo/cli'
184
+ CLI.warn "Feature #{feature} needs #{need}, disabling"
185
+ end
186
+ end
187
+ }
188
+ }
189
+
190
+ stages.callbacks(:initialized).do(self)
191
+
192
+ @@last = self
193
+ end
194
+
195
+ def create!
196
+ FileUtils.mkpath self.workdir
197
+ FileUtils.mkpath self.distdir
198
+ FileUtils.mkpath self.tempdir
199
+ rescue; end
200
+
201
+ def clean!
202
+ FileUtils.rm_rf self.workdir, secure: true
203
+ FileUtils.rm_rf self.distdir, secure: true
204
+ FileUtils.rm_rf self.tempdir, secure: true
205
+ rescue; end
206
+
207
+ def dependencies_check
208
+ stages.callbacks(:dependencies).do(self)
209
+ end
210
+
211
+ def blockers_check
212
+ stages.callbacks(:blockers).do(self)
213
+ end
214
+
215
+ def build
216
+ self.create!
217
+
218
+ @build_start_at = Time.now
219
+
220
+ stages.callbacks(:build).do(self) {
221
+ stages.each {|stage|
222
+ yield stage if block_given?
223
+
224
+ stage.call
225
+ }
226
+ }
227
+
228
+ @build_end_at = Time.now
229
+ end
230
+
231
+ def build?
232
+ Hash[
233
+ start: @build_start_at,
234
+ end: @build_end_at
235
+ ] if @build_start_at
236
+ end
237
+
238
+ def use (klass)
239
+ @modules << klass.new(self)
240
+ end
241
+
242
+ def avoid (klass)
243
+ [klass].flatten.compact.each {|klass|
244
+ @modules.delete(@modules.find {|mod|
245
+ mod.class == klass
246
+ }).finalize rescue nil
247
+ }
248
+ end
249
+
250
+ def behavior (uses)
251
+ uses.each {|use|
252
+ self.use(use)
253
+ }
254
+ end
255
+
256
+ def features (&block)
257
+ block.nil? ? @features : @features.instance_eval(&block)
258
+ end
259
+
260
+ def flavor (&block)
261
+ if !block
262
+ @flavor
263
+ else
264
+ @flavor.instance_eval &block
265
+ end
266
+ end
267
+
268
+ def package; self end
269
+
270
+ def to_s (type=nil)
271
+ return super(type) if super(type)
272
+
273
+ case type
274
+ when :package; "#{name}-#{version}#{"%#{slot}" if slot}#{"+#{@flavor.to_s(:package)}" if !@flavor.to_s(:package).empty?}#{"-#{@features.to_s(:package)}" if !@features.to_s(:package).empty?}"
275
+ when :everything; "#{super(:whole)} #{package.env!.reject {|n| n == :DEBUG}.to_s }}"
276
+ else "#{super(:whole)}#{"[#{@features.to_s}]" if !@features.to_s.empty?}#{"{#{@flavor.to_s}}" if !@flavor.to_s.empty?}"
277
+ end
278
+ end
279
+ end
280
+
281
+ end; end