vanagon 0.3.18

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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +175 -0
  4. data/bin/build +33 -0
  5. data/bin/devkit +22 -0
  6. data/bin/repo +26 -0
  7. data/bin/ship +15 -0
  8. data/lib/vanagon.rb +8 -0
  9. data/lib/vanagon/common.rb +2 -0
  10. data/lib/vanagon/common/pathname.rb +87 -0
  11. data/lib/vanagon/common/user.rb +25 -0
  12. data/lib/vanagon/component.rb +157 -0
  13. data/lib/vanagon/component/dsl.rb +307 -0
  14. data/lib/vanagon/component/source.rb +66 -0
  15. data/lib/vanagon/component/source/git.rb +60 -0
  16. data/lib/vanagon/component/source/http.rb +158 -0
  17. data/lib/vanagon/driver.rb +112 -0
  18. data/lib/vanagon/engine/base.rb +82 -0
  19. data/lib/vanagon/engine/docker.rb +40 -0
  20. data/lib/vanagon/engine/local.rb +40 -0
  21. data/lib/vanagon/engine/pooler.rb +85 -0
  22. data/lib/vanagon/errors.rb +28 -0
  23. data/lib/vanagon/extensions/string.rb +11 -0
  24. data/lib/vanagon/optparse.rb +62 -0
  25. data/lib/vanagon/platform.rb +245 -0
  26. data/lib/vanagon/platform/deb.rb +71 -0
  27. data/lib/vanagon/platform/dsl.rb +293 -0
  28. data/lib/vanagon/platform/osx.rb +100 -0
  29. data/lib/vanagon/platform/rpm.rb +76 -0
  30. data/lib/vanagon/platform/rpm/wrl.rb +39 -0
  31. data/lib/vanagon/platform/solaris_10.rb +182 -0
  32. data/lib/vanagon/platform/solaris_11.rb +138 -0
  33. data/lib/vanagon/platform/swix.rb +35 -0
  34. data/lib/vanagon/project.rb +251 -0
  35. data/lib/vanagon/project/dsl.rb +218 -0
  36. data/lib/vanagon/utilities.rb +299 -0
  37. data/spec/fixures/component/invalid-test-fixture.json +3 -0
  38. data/spec/fixures/component/mcollective.service +1 -0
  39. data/spec/fixures/component/test-fixture.json +4 -0
  40. data/spec/lib/vanagon/common/pathname_spec.rb +103 -0
  41. data/spec/lib/vanagon/common/user_spec.rb +36 -0
  42. data/spec/lib/vanagon/component/dsl_spec.rb +443 -0
  43. data/spec/lib/vanagon/component/source/git_spec.rb +19 -0
  44. data/spec/lib/vanagon/component/source/http_spec.rb +43 -0
  45. data/spec/lib/vanagon/component/source_spec.rb +99 -0
  46. data/spec/lib/vanagon/component_spec.rb +22 -0
  47. data/spec/lib/vanagon/engine/base_spec.rb +40 -0
  48. data/spec/lib/vanagon/engine/docker_spec.rb +40 -0
  49. data/spec/lib/vanagon/engine/pooler_spec.rb +54 -0
  50. data/spec/lib/vanagon/platform/deb_spec.rb +60 -0
  51. data/spec/lib/vanagon/platform/dsl_spec.rb +128 -0
  52. data/spec/lib/vanagon/platform/rpm_spec.rb +41 -0
  53. data/spec/lib/vanagon/platform/solaris_11_spec.rb +44 -0
  54. data/spec/lib/vanagon/platform_spec.rb +53 -0
  55. data/spec/lib/vanagon/project/dsl_spec.rb +203 -0
  56. data/spec/lib/vanagon/project_spec.rb +44 -0
  57. data/spec/lib/vanagon/utilities_spec.rb +140 -0
  58. data/templates/Makefile.erb +116 -0
  59. data/templates/deb/changelog.erb +5 -0
  60. data/templates/deb/conffiles.erb +3 -0
  61. data/templates/deb/control.erb +21 -0
  62. data/templates/deb/dirs.erb +3 -0
  63. data/templates/deb/docs.erb +1 -0
  64. data/templates/deb/install.erb +3 -0
  65. data/templates/deb/postinst.erb +46 -0
  66. data/templates/deb/postrm.erb +15 -0
  67. data/templates/deb/prerm.erb +17 -0
  68. data/templates/deb/rules.erb +25 -0
  69. data/templates/osx/postinstall.erb +24 -0
  70. data/templates/osx/preinstall.erb +19 -0
  71. data/templates/osx/project-installer.xml.erb +19 -0
  72. data/templates/rpm/project.spec.erb +217 -0
  73. data/templates/solaris/10/depend.erb +3 -0
  74. data/templates/solaris/10/pkginfo.erb +13 -0
  75. data/templates/solaris/10/postinstall.erb +37 -0
  76. data/templates/solaris/10/preinstall.erb +7 -0
  77. data/templates/solaris/10/preremove.erb +6 -0
  78. data/templates/solaris/10/proto.erb +5 -0
  79. data/templates/solaris/11/p5m.erb +73 -0
  80. metadata +172 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0273c4745ecf7c50f369b6ea518caf46b92c8e07
4
+ data.tar.gz: 06437a1d3f2838cfd97d673fe2f82981ca917df0
5
+ SHA512:
6
+ metadata.gz: 2664084d24f35b26e7b30b4ab20c0ee910281af1722ac82363696de47af77962eb1f9cd3980f3d6af8a3aa10a0472f890f27eae66557c0c5a0aadeca96007852
7
+ data.tar.gz: f27159049e709a19879702636296d27ab31d2c40455f0c11675616a75a3c96411a017f9fefc1fec0ee460dbd4c0443a64e5f6549dbe3a48fc009f28f4d0cc551
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2014-2015 Puppet Labs
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,175 @@
1
+ ![Build Status](https://magnum.travis-ci.com/puppetlabs/vanagon.svg?token=A9NWBM3ogJqUCfos2gVF&branch=master)
2
+ The Vanagon Project
3
+ ===
4
+ * What is vanagon?
5
+ * Runtime requirements
6
+ * Configuration and Usage
7
+ * Overview
8
+ * Contributing
9
+ * License
10
+ * Maintainers
11
+
12
+ What is vanagon?
13
+ ---
14
+ Vanagon is a tool to build a single package out of a project, which can itself
15
+ contain one or more components. This tooling is being used to develop the
16
+ puppet-agent package, which contains components such as openssl, ruby, and
17
+ augeas among others. For a simple example, please see the examples directory.
18
+
19
+ Vanagon builds up a Makefile and packaging files (specfile for RPM,
20
+ control/rules/etc for DEB) and copies them to a remote host, where make can be
21
+ invoked to build all of the components and make a package of the contents.
22
+
23
+ Vanagon also provides a devkit command that will prepare a machine as a
24
+ development environment for the entire project, or restricted to individual
25
+ components of the project. The devkit command installs all required build tools,
26
+ creates a master makefile for the project, and configures, builds, and installs
27
+ all components. The result is an environment where you can work on individual
28
+ components, then rebuild the project and test the installed artifacts.
29
+
30
+ Runtime Requirements
31
+ ---
32
+ Vanagon is self-contained. A recent version of ruby should be all that is
33
+ required. Beyond that, ssh, rsync and git are also required on the host, and
34
+ ssh-server and rsync is required on the target (package installation for the
35
+ target can be customized in the platform config for the target).
36
+
37
+ Configuration and Usage
38
+ ---
39
+ Vanagon won't be much use without a project to build. Beyond that, you must
40
+ define any platforms you want to build for. Vanagon ships with some simple
41
+ binaries to use, but the one you probably care about is named 'build'.
42
+
43
+ ### `build` usage
44
+
45
+ The build command has positional arguments and position independent flags.
46
+
47
+ #### Arguments (position dependent)
48
+
49
+ ##### project name
50
+ The name of the project to build, and a file named \<project\_name\>.rb must be
51
+ present in configs/projects in the working directory.
52
+
53
+ ##### platform name
54
+ The name of the platform to build against, and a file named
55
+ \<platform\_name\>.rb must be present in configs/platforms in the working
56
+ directory.
57
+
58
+ Platform can also be a comma separated list of platforms such as platform1,platform2.
59
+
60
+ ##### target host [optional]
61
+ Target host is an optional argument to override the host selection. Instead of using
62
+ a vm collected from the pooler, the build will attempt to ssh to target as the
63
+ root user.
64
+
65
+ If building on multiple platforms, multiple targets can also be specified using
66
+ a comma separated list such as host1,host2. If less targets are specified than
67
+ platforms, the default engine (the pooler) will be used for platforms without a
68
+ target. If more targets are specified than platforms, the extra will be ignored.
69
+
70
+ #### Flagged arguments (can be anywhere in the command)
71
+
72
+ ##### -w DIR, --workdir DIR
73
+ Specifies a directory where the sources should be placed and builds performed.
74
+ Defaults to a temporary directory created with Ruby's Dir.mktmpdir.
75
+
76
+ ##### -c DIR, --configdir DIR
77
+ Specifies where project configuration is found. Defaults to $pwd/configs.
78
+
79
+ ##### -e ENGINE, --engine ENGINE
80
+ Choose a different virtualization engine to use to select the build target.
81
+ Currently supported engines are:
82
+ * `base` - Pure ssh backend; no teardown currently defined
83
+ * `local` - Build on the local machine; platform name must match the local machine
84
+ * `docker` - Builds in a docker container
85
+ * `pooler` - Selects a vm from Puppet Labs' vm pooler to build on
86
+
87
+ #### Flags (can be anywhere in the command)
88
+
89
+ ##### -p, --preserve
90
+ Indicates that the host used for building the project should be left intact
91
+ after the build instead of destroyed. The host is usually destroyed after a
92
+ successful build, or left after a failed build.
93
+
94
+ ##### -v, --verbose (not yet implemented)
95
+ Increase verbosity of output.
96
+
97
+ ##### -h, --help
98
+ Display command-line help.
99
+
100
+ #### Environment variables
101
+
102
+ ##### VANAGON\_SSH\_KEY
103
+ A full path on disk for a private ssh key to be used in ssh and rsync
104
+ communications. This will be used instead of whatever defaults are configured
105
+ in .ssh/config.
106
+
107
+ ##### VMPOOLER\_TOKEN
108
+ Used in conjunction with the pooler engine, this is a token to pass to the
109
+ vmpooler to access the API. Without this token, the default lifetime of vms
110
+ will be much shorter.
111
+
112
+ #### Example usage
113
+ `build --preserve puppet-agent el-6-i386` will build the puppet-agent project
114
+ on the el-6-i386 platform and leave the host intact afterward.
115
+
116
+ `build --engine=docker puppet-agent el-6-i386` will build the puppet-agent
117
+ project on the el-6-i386 platform using the docker engine (the platform must
118
+ have a docker\_image defined in its config).
119
+
120
+ ### `devkit` usage
121
+
122
+ The devkit command has positional arguments and position independent flagged
123
+ arguments.
124
+
125
+ #### Arguments (position dependent)
126
+
127
+ ##### project name
128
+ As in `build` arguments.
129
+
130
+ ##### platform name
131
+ As in `build` arguments.
132
+
133
+ ##### component names [optional]
134
+ Specifies specific components that should be built. If components are not
135
+ specified, then all components in the project will be built. If components
136
+ are specified as arguments, then any in the project that aren't specified
137
+ as arguments will be retrieved from packages rather than built from source.
138
+
139
+ #### Flagged arguments (can be anywhere in the command)
140
+
141
+ Supports all flagged arguments from the `build` command.
142
+
143
+ ##### -t HOST, --target HOST
144
+ As in the `build` target host optional argument.
145
+
146
+ #### Flags (can be anywhere in the command)
147
+
148
+ ##### -h, --help
149
+ Display command-line help.
150
+
151
+ Contributing
152
+ ---
153
+ We'd love to get contributions from you! Once you are up and running, take a look at the
154
+ [Contribution Documents](CONTRIBUTING.md) to see how to get your changes merged
155
+ in.
156
+
157
+ License
158
+ ---
159
+ See [LICENSE](LICENSE) file.
160
+
161
+ Overview
162
+ ---
163
+ Vanagon is broken down into three core ideas: the project, the component and
164
+ the platform. The project contains one or more components and is built for a
165
+ platform. As a quick example, if I had a ruby app and wanted to package it, the
166
+ project would probably contain a component for ruby and a component for my app.
167
+ If I wanted to build it for debian wheezy, I would define a platform called
168
+ wheezy and build my project against it.
169
+
170
+ For more detailed examples of the DSLs available, please see the
171
+ [examples](examples) directory and the YARD documentation for vanagon.
172
+
173
+ Maintainers
174
+ ---
175
+ The Release Engineering team at Puppet Labs
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ load File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "vanagon.rb"))
3
+
4
+ optparse = Vanagon::OptParse.new("#{File.basename(__FILE__)} <project-name> <platform-name> [<target>] [options]",
5
+ [:workdir, :configdir, :engine, :preserve, :verbose])
6
+ options = optparse.parse! ARGV
7
+
8
+ project = ARGV[0]
9
+ platforms = ARGV[1]
10
+ targets = ARGV[2]
11
+
12
+ if project.nil? or platforms.nil?
13
+ warn "project and platform are both required arguments."
14
+ puts optparse
15
+ exit 1
16
+ end
17
+
18
+ platform_list = platforms.split(',')
19
+ if targets
20
+ target_list = targets.split(',')
21
+ else
22
+ target_list = []
23
+ end
24
+
25
+ platform_list.zip(target_list).each do |pair|
26
+ platform, target = pair
27
+ artifact = Vanagon::Driver.new(platform, project, options.merge({ :target => target }))
28
+
29
+ artifact.verbose = true if options[:verbose]
30
+ artifact.preserve = true if options[:preserve]
31
+
32
+ artifact.run
33
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ load File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "vanagon.rb"))
3
+
4
+ optparse = Vanagon::OptParse.new("#{File.basename(__FILE__)} <project-name> <platform-name> [<component-name>...] [options]",
5
+ [:workdir, :configdir, :target, :engine])
6
+ options = optparse.parse! ARGV
7
+
8
+ project = ARGV[0]
9
+ platform = ARGV[1]
10
+ components = ARGV.drop(2)
11
+
12
+ if project.nil? or platform.nil?
13
+ warn "project and platform are both required arguments."
14
+ puts optparse
15
+ exit 1
16
+ end
17
+
18
+ artifact = Vanagon::Driver.new(platform, project, options.merge({ :components => components }))
19
+
20
+ artifact.preserve = true
21
+
22
+ artifact.prepare(options[:workdir])
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV["PROJECT_ROOT"] = Dir.pwd
4
+
5
+ # Begin warning: This ship script is an internal tool.
6
+ # This is not intended to function outside of Puppet Labs' infrastructure.
7
+ # This presumes packages for this ref have already been build and shipped.
8
+ # End of warning.
9
+
10
+ # repo_target will allow us to be more granular with the selection of repos that will be constructed
11
+ # if we have not built debs or rpms, the packaging repo will fail when creating repos
12
+ if ARGV[0]
13
+ repo_target = ARGV[0].downcase
14
+ end
15
+
16
+ require 'packaging'
17
+ Pkg::Util::RakeUtils.load_packaging_tasks
18
+ case repo_target
19
+ when 'rpm'
20
+ Pkg::Util::RakeUtils.invoke_task('pl:jenkins:rpm_repos')
21
+ when 'deb'
22
+ Pkg::Util::RakeUtils.invoke_task('pl:jenkins:deb_repos')
23
+ else
24
+ Pkg::Util::RakeUtils.invoke_task('pl:jenkins:rpm_repos')
25
+ Pkg::Util::RakeUtils.invoke_task('pl:jenkins:deb_repos')
26
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV["PROJECT_ROOT"] = Dir.pwd
4
+
5
+ # Begin warning: This ship script is an internal tool.
6
+ # This is not intended to function outside of Puppet Labs' infrastructure.
7
+ # End of warning.
8
+
9
+ if Dir["output/**/*"].select { |entry| File.file?(entry) }.empty?
10
+ fail "No packages to ship in the output directory. Maybe you want to build some first?"
11
+ else
12
+ require 'packaging'
13
+ Pkg::Util::RakeUtils.load_packaging_tasks
14
+ Pkg::Util::RakeUtils.invoke_task('pl:jenkins:ship', 'artifacts', 'output')
15
+ end
@@ -0,0 +1,8 @@
1
+ LIBDIR = File.expand_path(File.dirname(__FILE__))
2
+ VANAGON_ROOT = File.join(File.expand_path(File.dirname(__FILE__)), "..")
3
+
4
+ $:.unshift(LIBDIR) unless
5
+ $:.include?(File.dirname(__FILE__)) || $:.include?(LIBDIR)
6
+
7
+ require 'vanagon/optparse'
8
+ require 'vanagon/driver'
@@ -0,0 +1,2 @@
1
+ require 'vanagon/common/pathname'
2
+ require 'vanagon/common/user'
@@ -0,0 +1,87 @@
1
+ class Vanagon
2
+ class Common
3
+ class Pathname
4
+ # @!attribute path
5
+ # @return [String] Returns clean pathname of self with consecutive
6
+ # slashes and useless dots removed. The filesystem is not accessed.
7
+ #
8
+ # @!attribute mode
9
+ # @return [String, Integer] Returns an integer representing the
10
+ # permission bits of self. The meaning of the bits is platform
11
+ # dependent; on Unix systems, see stat(2).
12
+ #
13
+ # @!attribute owner
14
+ # @return [String, Integer] Returns the numeric user id or string
15
+ # representing the user name of the owner of self.
16
+ #
17
+ # @!attribute group
18
+ # @return [String, Integer] Returns the numeric group id or string
19
+ # representing the group name of the owner of self.
20
+ attr_accessor :path, :mode, :owner, :group
21
+
22
+ # Each Pathname requires a filesystem path, and has many optional
23
+ # properties that may be set at initialization time.
24
+ # @param [String, Integer] mode the UNIX Octal permission string to use when this file is archived
25
+ # @param [String, Integer] owner the username or UID to use when this file is archived
26
+ # @param [String, Integer] group the groupname or GID to use when this file is archived
27
+ # @param [Boolean] config mark this file as a configuration file, stored as private state
28
+ # and exposed through the {#configfile?} method.
29
+ # @return [Vanagon::Common::Pathname] Returns a new Pathname instance.
30
+ def initialize(path, mode: nil, owner: nil, group: nil, config: false)
31
+ @path = File.expand_path(path)
32
+ @mode ||= mode
33
+ @owner ||= owner
34
+ @group ||= group
35
+ @config ||= config
36
+ end
37
+
38
+ # An alias to {Vanagon::Common::Pathname}'s constructor method,
39
+ # which returns a new Vanagon::Common::Pathname, explicitly marked as a file
40
+ # @see Vanagon::Common::Pathname#initialize
41
+ #
42
+ # @example Create a new Vanagon::Common::Pathname, marked as a file.
43
+ # Vanagon::Common::Pathname.file('/etc/puppet/puppet/puppet.conf')
44
+ def self.file(path, **args)
45
+ new(path, **args.merge!({ config: false}))
46
+ end
47
+
48
+ # An alias to {Vanagon::Common::Pathname}'s constructor method,
49
+ # which returns a new Vanagon::Common::Pathname, explicitly marked as a configuration file
50
+ # @see Vanagon::Common::Pathname#initialize
51
+ #
52
+ # @example Create a new configuration file, marked as a configuration file.
53
+ # Vanagon::Common::Pathname.configfile('/etc/puppet/puppet/puppet.conf')
54
+ def self.configfile(path, **args)
55
+ new(path, **args.merge!({ config: true}))
56
+ end
57
+
58
+ # @return [Boolean] true if a self is marked as a configuration file.
59
+ def configfile?
60
+ !!@config
61
+ end
62
+
63
+ # Simple test to see if any of the non-required attributes have been set in this object.
64
+ #
65
+ # @return [Boolean] whether or not mode, owner or group has been set for the object
66
+ def has_overrides?
67
+ !!(@mode || @owner || @group)
68
+ end
69
+
70
+ # Equality -- Two instances of Vanagon::Common::Pathname are equal if they
71
+ # contain the same number attributes and if each attribute is equal to
72
+ # (according to {Object#==}) the corresponding attribute in other_pathname.
73
+ #
74
+ # @return [Boolean] true if all attributes have equal values, or otherwise false.
75
+ def ==(other)
76
+ other.hash == hash
77
+ end
78
+ alias :eql? :==
79
+
80
+ # @return [Fixnum] Compute a hash-code for self, derived from its attributes;
81
+ # two Pathnames with the same content will have the same hash code (and will compare using {#eql?}).
82
+ def hash
83
+ instance_variables.map { |v| instance_variable_get(v) }.hash
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,25 @@
1
+ class Vanagon
2
+ class Common
3
+ class User
4
+ attr_accessor :name, :group, :shell, :is_system, :homedir
5
+ def initialize(name, group = nil, shell = nil, is_system = false, homedir = nil)
6
+ @name = name
7
+ @group = group ? group : @name
8
+ @shell = shell if shell
9
+ @is_system = is_system if is_system
10
+ @homedir = homedir if homedir
11
+ end
12
+
13
+ # Equality. How does it even work?
14
+ #
15
+ # @return [true, false] true if all attributes have equal values. false otherwise.
16
+ def ==(other)
17
+ other.name == self.name && \
18
+ other.group == self.group && \
19
+ other.shell == self.shell && \
20
+ other.is_system == self.is_system && \
21
+ other.homedir == self.homedir
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,157 @@
1
+ require 'vanagon/component/source'
2
+ require 'vanagon/component/dsl'
3
+
4
+ class Vanagon
5
+ class Component
6
+ # @!attribute [r] files
7
+ # @return [Set] the list of files marked for installation
8
+
9
+ attr_accessor :name, :version, :source, :url, :configure, :build, :install
10
+ attr_accessor :environment, :extract_with, :dirname, :build_requires
11
+ attr_accessor :settings, :platform, :patches, :requires, :service, :options
12
+ attr_accessor :directories, :replaces, :provides, :cleanup_source, :environment
13
+ attr_accessor :sources, :preinstall_actions, :postinstall_actions
14
+
15
+ # Loads a given component from the configdir
16
+ #
17
+ # @param name [String] the name of the component
18
+ # @param configdir [String] the path to the component config file
19
+ # @param settings [Hash] the settings to be used in the component
20
+ # @param platform [Vanagon::Platform] the platform to build the component for
21
+ # @return [Vanagon::Component] the component as specified in the component config
22
+ # @raise if the instance_eval on Component fails, the exception is reraised
23
+ def self.load_component(name, configdir, settings, platform)
24
+ compfile = File.join(configdir, "#{name}.rb")
25
+ code = File.read(compfile)
26
+ dsl = Vanagon::Component::DSL.new(name, settings, platform)
27
+ dsl.instance_eval(code, __FILE__, __LINE__)
28
+ dsl._component
29
+ rescue => e
30
+ puts "Error loading project '#{name}' using '#{compfile}':"
31
+ puts e
32
+ puts e.backtrace.join("\n")
33
+ raise e
34
+ end
35
+
36
+ # Component constructor.
37
+ #
38
+ # @param name [String] the name of the component
39
+ # @param settings [Hash] the settings to be used in the component
40
+ # @param platform [Vanagon::Platform] the platform to build the component for
41
+ # @return [Vanagon::Component] the component with the given settings and platform
42
+ def initialize(name, settings, platform)
43
+ @name = name
44
+ @settings = settings
45
+ @platform = platform
46
+ @options = {}
47
+ @build_requires = []
48
+ @requires = []
49
+ @configure = []
50
+ @install = []
51
+ @build = []
52
+ @patches = []
53
+ @files = Set.new
54
+ @directories = []
55
+ @replaces = []
56
+ @provides = []
57
+ @environment = {}
58
+ @sources = []
59
+ @preinstall_actions = []
60
+ @postinstall_actions = []
61
+ end
62
+
63
+ # Adds the given file to the list of files and returns @files.
64
+ #
65
+ # @param file [Vanagon::Common::Pathname] file to add to a component's list of files
66
+ # @return [Set, nil] Returns @files if file is successfully added to @files
67
+ # or nil if file already exists
68
+ def add_file(file)
69
+ @files.add file
70
+ end
71
+
72
+ # Deletes the given file from the list of files and returns @files.
73
+ #
74
+ # @param file [String] path of file to delete from a component's list of files
75
+ # @return [Set, nil] Returns @files if file is successfully deleted
76
+ # from @files or nil if file doesn't exist; this matches strictly on
77
+ # the path of a given file, and ignores other attributes like :mode,
78
+ # :owner, or :group.
79
+ def delete_file(file)
80
+ @files.delete_if { |this_file| this_file.path == file }
81
+ end
82
+
83
+ # Retrieve all items from @files not marked as configuration files
84
+ #
85
+ # @return [Set] all files not marked as configuration files
86
+ def files
87
+ @files.reject(&:configfile?)
88
+ end
89
+
90
+ # Retrieve all items from @files explicitly marked as configuration files
91
+ #
92
+ # @return [Set] all files explicitly marked as configuration files
93
+ def configfiles
94
+ @files.select(&:configfile?)
95
+ end
96
+
97
+ # Fetches the primary source for the component. As a side effect, also sets
98
+ # \@extract_with, @dirname and @version for the component for use in the
99
+ # makefile template
100
+ #
101
+ # @param workdir [String] working directory to put the source into
102
+ def get_source(workdir)
103
+ if @url
104
+ @source = Vanagon::Component::Source.source(@url, @options, workdir)
105
+ @source.fetch
106
+ @source.verify
107
+ @extract_with = @source.extract(@platform.tar) if @source.respond_to?(:extract)
108
+ @cleanup_source = @source.cleanup if @source.respond_to?(:cleanup)
109
+ @dirname = @source.dirname
110
+
111
+ # Git based sources probably won't set the version, so we load it if it hasn't been already set
112
+ @version ||= @source.version
113
+ else
114
+ warn "No source given for component '#{@name}'"
115
+
116
+ # If there is no source, we don't want to try to change directories, so we just change to the current directory.
117
+ @dirname = './'
118
+ end
119
+ end
120
+
121
+
122
+ # Fetches secondary sources for the component. These are just dumped into the workdir currently.
123
+ #
124
+ # @param workdir [String] working directory to put the source into
125
+ def get_sources(workdir)
126
+ @sources.each do |source|
127
+ cur_source = Vanagon::Component::Source.source(source.url, { :ref => source.ref, :sum => source.sum }, workdir)
128
+ cur_source.fetch
129
+ cur_source.verify
130
+ end
131
+ end
132
+
133
+ # Fetches patches if any are provided for the project.
134
+ #
135
+ # @param workdir [String] working directory to put the patches into
136
+ def get_patches(workdir)
137
+ unless @patches.empty?
138
+ patchdir = File.join(workdir, "patches")
139
+ FileUtils.mkdir_p(patchdir)
140
+ FileUtils.cp(@patches.map(&:path), patchdir)
141
+ end
142
+ end
143
+
144
+ # Prints the environment in a way suitable for use in a Makefile
145
+ # or shell script.
146
+ #
147
+ # @return [String] environment suitable for inclusion in a Makefile
148
+ def get_environment
149
+ if @environment.empty?
150
+ ":"
151
+ else
152
+ env = @environment.map { |key, value| %(#{key}="#{value}") }
153
+ "export #{env.join(' ')}"
154
+ end
155
+ end
156
+ end
157
+ end