vanagon 0.9.3 → 0.10.0

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.
@@ -24,6 +24,7 @@ class Vanagon
24
24
  # @param block [Proc] DSL definition of the project to call
25
25
  def project(name, &block)
26
26
  yield(self)
27
+ environment 'VANAGON_PROJECT', @name
27
28
  end
28
29
 
29
30
  # Accessor for the project.
@@ -81,6 +82,9 @@ class Vanagon
81
82
  # @param the_name [String] name of the project
82
83
  def name(the_name)
83
84
  @project.name = the_name
85
+ # Overwrite the environment variable name using the reset name
86
+ # of the project.
87
+ environment 'VANAGON_PROJECT_NAME', @project.name
84
88
  end
85
89
 
86
90
  # Sets the homepage for the project. Mainly for use in packaging.
@@ -95,6 +99,7 @@ class Vanagon
95
99
  # @param page [Integer] timeout in seconds
96
100
  def timeout(to)
97
101
  @project.timeout = to
102
+ environment 'VANAGON_PROJECT_TIMEOUT', @project.timeout
98
103
  end
99
104
 
100
105
  # Sets the run time requirements for the project. Mainly for use in packaging.
@@ -135,6 +140,7 @@ class Vanagon
135
140
  # @param ver [String] version of the project
136
141
  def version(ver)
137
142
  @project.version = ver.tr('-', '.')
143
+ environment 'VANAGON_PROJECT_VERSION', @project.version
138
144
  end
139
145
 
140
146
  # Sets the release for the project. Mainly for use in packaging.
@@ -142,6 +148,7 @@ class Vanagon
142
148
  # @param rel [String] release of the project
143
149
  def release(rel)
144
150
  @project.release = rel
151
+ environment 'VANAGON_PROJECT_RELEASE', @project.release
145
152
  end
146
153
 
147
154
  # Sets the version for the project based on a git describe of the
@@ -149,8 +156,8 @@ class Vanagon
149
156
  # and reachable from the current commit in that repository.
150
157
  #
151
158
  def version_from_git
152
- version = Git.open(File.expand_path("..", Vanagon::Driver.configdir)).describe('HEAD', tags: true)
153
- @project.version = version.split('-').reject(&:empty?).join('.')
159
+ git_version = Git.open(File.expand_path("..", Vanagon::Driver.configdir)).describe('HEAD', tags: true)
160
+ version(git_version.split('-').reject(&:empty?).join('.'))
154
161
  rescue Git::GitExecuteError
155
162
  warn "Directory '#{dirname}' cannot be versioned by git. Maybe it hasn't been tagged yet?"
156
163
  end
@@ -160,6 +167,7 @@ class Vanagon
160
167
  # @param vend [String] vendor or author of the project
161
168
  def vendor(vend)
162
169
  @project.vendor = vend
170
+ environment 'VANAGON_PROJECT_VENDOR', @project.vendor
163
171
  end
164
172
 
165
173
  # Adds a directory to the list of directories provided by the project, to be included in any packages of the project
@@ -172,6 +180,12 @@ class Vanagon
172
180
  @project.directories << Vanagon::Common::Pathname.new(dir, mode: mode, owner: owner, group: group)
173
181
  end
174
182
 
183
+ # Adds an arbitrary environment variable to the project, which will be passed
184
+ # on to the platform and inherited by any components built on that platform
185
+ def environment(name, value)
186
+ @project.environment[name] = value
187
+ end
188
+
175
189
  # Add a user to the project
176
190
  #
177
191
  # @param name [String] name of the user to create
@@ -248,6 +262,7 @@ class Vanagon
248
262
  # Counter for the number of times a project should retry a task
249
263
  def retry_count(retry_count)
250
264
  @project.retry_count = retry_count
265
+ environment 'VANAGON_PROJECT_RETRY_COUNT', @project.retry_count
251
266
  end
252
267
  end
253
268
  end
@@ -264,6 +264,8 @@ class Vanagon
264
264
  template = File.read(erbfile)
265
265
  message = ERB.new(template, nil, "-")
266
266
  message.result(b)
267
+ .gsub(/[\n]+{3,}/, "\n\n")
268
+ .squeeze("\s")
267
269
  end
268
270
 
269
271
  # Helper method that takes a template and writes the evaluated contents to a file on disk
@@ -1,11 +1,15 @@
1
- <% dirnames = get_directories.map {|d| d.path } %>
2
- export SHELL := $(shell which bash)
1
+ SHELL = $(PWD)/profiling_shell.sh
2
+
3
+ <%- merged_environment.to_a(" := ").each do |var| -%>
4
+ export <%= var %>
5
+ <%- end -%>
3
6
 
4
7
  tempdir := $(shell mktemp -d -p /var/tmp 2>/dev/null || mktemp -d -t 'tmp')
5
8
  workdir := $(PWD)
6
9
 
7
10
  all: file-list-before-build <%= package_name %>
8
11
 
12
+ <%= package_name %>: export VANAGON_TARGET := create-package
9
13
  <%= package_name %>: <%= @name %>-<%= @version %>.tar.gz
10
14
  <%= generate_package.join("\n\t") %>
11
15
 
@@ -13,14 +17,14 @@ file-list-before-build:
13
17
  <%- if dirnames.empty? -%>
14
18
  touch file-list-before-build
15
19
  <%- else -%>
16
- (<%= @platform.find %> -H "<%= dirnames.join('" "') %>" 2>/dev/null || <%= @platform.find %> "<%= dirnames.join('" "') %>" 2>/dev/null) | <%= "xargs -I[] cygpath --mixed --long-name --absolute [] |" if @platform.is_windows? %> <%= @platform.sort %> | uniq > file-list-before-build
20
+ (<%= @platform.find %> -L "<%= dirnames.join('" "') %>" 2>/dev/null || <%= @platform.find %> "<%= dirnames.join('" "') %>" -follow 2>/dev/null) | <%= "xargs -I[] cygpath --mixed --long-name --absolute [] |" if @platform.is_windows? %> <%= @platform.sort %> | uniq > file-list-before-build
17
21
  <%- end -%>
18
22
 
19
23
  file-list-after-build: <%= @components.map {|comp| comp.name }.join(" ") %>
20
24
  <%- if dirnames.empty? -%>
21
25
  touch file-list-after-build
22
26
  <%- else -%>
23
- (<%= @platform.find %> -H "<%= dirnames.join('" "') %>" 2>/dev/null || <%= @platform.find %> "<%= dirnames.join('" "') %>" 2>/dev/null) | <%= "xargs -I[] cygpath --mixed --long-name --absolute [] |" if @platform.is_windows? %> <%= @platform.sort %> | uniq > file-list-after-build
27
+ (<%= @platform.find %> -L "<%= dirnames.join('" "') %>" 2>/dev/null || <%= @platform.find %> "<%= dirnames.join('" "') %>" -follow 2>/dev/null) | <%= "xargs -I[] cygpath --mixed --long-name --absolute [] |" if @platform.is_windows? %> <%= @platform.sort %> | uniq > file-list-after-build
24
28
  <%- end -%>
25
29
 
26
30
  <%= @name %>-<%= @version %>.tar.gz: file-list <%= @cleanup ? 'cleanup-components' : '' %>
@@ -0,0 +1,45 @@
1
+ #!/bin/bash
2
+
3
+ # this variant of the Profiling shell wrapper
4
+ # uses only the Bash keyword `time`, and the generally
5
+ # standard command `tee` to get run time. This was
6
+ # needed because the BSD/sysv variants of `date` only
7
+ # offer second-resolution. No milliseconds, no nano-
8
+ # seconds.
9
+
10
+ # Create copies of stdout & stderr's file descriptors
11
+ # so that the output of the subshell that `time` runs
12
+ # can be captured and used.
13
+ exec 3>&1
14
+ exec 4>&2
15
+
16
+ # Write some log files, that can be post-processed
17
+ # relatively easily.
18
+ __stdout="${VANAGON_TARGET}.stdout.log"
19
+ __stderr="${VANAGON_TARGET}.stderr.log"
20
+
21
+ # Define a default time format (seconds and milliseconds),
22
+ # and then use some insane output redirection hacks to capture
23
+ # the output of the `time` keyword. We're using `tee` to
24
+ # output to stdout & stderr but we should figure out how to
25
+ # supress that for quieter Vanagon builds.
26
+ TIMEFORMAT='%3R'
27
+ __seconds="$( {
28
+ time bash -o pipefail "${@}" > >(tee -ai "${__stdout}" >&3) 2> >(tee -ai "${__stderr}" >&4 )
29
+ } 2>&1)"
30
+
31
+ # If any part of the pipeline failed, then
32
+ # this status should correspond to whatever
33
+ # failing status the pipeline returned. We
34
+ # want to check & preserve that.
35
+ if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
36
+ exit "${PIPESTATUS[0]}"
37
+ fi
38
+
39
+ # Finally, if everything completed successfully,
40
+ # finesse the numbers and fire them off to our
41
+ # statsd interface.
42
+ if [[ "${VANAGON_TARGET}" ]] && [[ "${VANAGON_STATSD_HOST}" ]] && [[ "${VANAGON_STATSD_PORT}" ]]; then
43
+ __elapsed="$(echo "scale=0;${__seconds}*1000/1" | bc -l)"
44
+ echo -n "vanagon.${VANAGON_PROJECT}.${VANAGON_PLATFORM}.${VANAGON_TARGET}:${__elapsed}|ms" > "/dev/udp/${VANAGON_STATSD_HOST}/${VANAGON_STATSD_PORT}"
45
+ fi
@@ -142,7 +142,7 @@ install -d %{buildroot}
142
142
 
143
143
  # Here we turn all dirs in the file-list into %dir entries to avoid duplicate files
144
144
  for entry in `cat %{SOURCE1}`; do
145
- if [ -n "$entry" -a -d "$entry" -a ! -L "$entry" ]; then
145
+ if [ -n "$entry" -a -d "$entry" ]; then
146
146
  PATH=/opt/freeware/bin:$PATH sed -i "s|^\($entry\)\$|%dir \1|g" %{SOURCE1}
147
147
  fi
148
148
  done
@@ -5,7 +5,7 @@ describe Makefile::Rule do
5
5
  subject { described_class.new("empty") }
6
6
 
7
7
  it "creates an empty rule" do
8
- expect(subject.format).to eq "empty:\n"
8
+ expect(subject.format).to eq "empty: export VANAGON_TARGET := empty\nempty:\n"
9
9
  end
10
10
  end
11
11
 
@@ -13,7 +13,7 @@ describe Makefile::Rule do
13
13
  subject { described_class.new("simple", recipe: ["touch simple"]) }
14
14
 
15
15
  it "creates the rule with the recipe" do
16
- expect(subject.format).to eq "simple:\n\ttouch simple\n"
16
+ expect(subject.format).to eq "simple: export VANAGON_TARGET := simple\nsimple:\n\ttouch simple\n"
17
17
  end
18
18
  end
19
19
 
@@ -21,7 +21,7 @@ describe Makefile::Rule do
21
21
  subject { described_class.new("depends", dependencies: ["mydeps"]) }
22
22
 
23
23
  it "creates the rule with the recipe" do
24
- expect(subject.format).to eq "depends: mydeps\n"
24
+ expect(subject.format).to eq "depends: export VANAGON_TARGET := depends\ndepends: mydeps\n"
25
25
  end
26
26
  end
27
27
 
@@ -29,7 +29,7 @@ describe Makefile::Rule do
29
29
  subject { described_class.new("deluxe", recipe: ["touch deluxe"], dependencies: ["mydeps"]) }
30
30
 
31
31
  it "creates the rule with the recipe" do
32
- expect(subject.format).to eq "deluxe: mydeps\n\ttouch deluxe\n"
32
+ expect(subject.format).to eq "deluxe: export VANAGON_TARGET := deluxe\ndeluxe: mydeps\n\ttouch deluxe\n"
33
33
  end
34
34
  end
35
35
 
@@ -44,7 +44,7 @@ describe Makefile::Rule do
44
44
  end
45
45
 
46
46
  it "inserts tabs after each newline in the recipe" do
47
- expect(subject.format).to eq "multiline:\n\t[ -d build ] || mkdir -p build\n\tcd build &&\n\tcmake .. &&\n\tmake &&\n\tmake install\n"
47
+ expect(subject.format).to eq "multiline: export VANAGON_TARGET := multiline\nmultiline:\n\t[ -d build ] || mkdir -p build\n\tcd build &&\n\tcmake .. &&\n\tmake &&\n\tmake install\n"
48
48
  end
49
49
  end
50
50
  end
@@ -587,14 +587,7 @@ end" }
587
587
  it 'adds the file to the configfiles list' do
588
588
  comp = Vanagon::Component::DSL.new('install-config-file-test', {}, platform)
589
589
  comp.install_configfile('thing1', 'place/to/put/thing1')
590
- expect(comp._component.configfiles).to include(Vanagon::Common::Pathname.configfile('place/to/put/thing1', mode: '0644'))
591
- expect(comp._component.files).not_to include(Vanagon::Common::Pathname.file('place/to/put/thing1'))
592
- end
593
-
594
- it 'sets owner, group, and mode for the configfiles' do
595
- comp = Vanagon::Component::DSL.new('install-config-file-test', {}, platform)
596
- comp.install_configfile('thing1', 'place/to/put/thing1', owner: 'bob', group: 'timmy', mode: '0022')
597
- expect(comp._component.configfiles).to include(Vanagon::Common::Pathname.configfile('place/to/put/thing1', mode: '0022', group: 'timmy', owner: 'bob'))
590
+ expect(comp._component.configfiles).to include(Vanagon::Common::Pathname.configfile('place/to/put/thing1'))
598
591
  expect(comp._component.files).not_to include(Vanagon::Common::Pathname.file('place/to/put/thing1'))
599
592
  end
600
593
  end
@@ -624,7 +617,7 @@ end" }
624
617
  it 'adds the file to the configfiles list' do
625
618
  comp = Vanagon::Component::DSL.new('install-config-file-test', {}, platform)
626
619
  comp.install_configfile('thing1', 'place/to/put/thing1')
627
- expect(comp._component.configfiles).to include(Vanagon::Common::Pathname.configfile('place/to/put/thing1.pristine', mode: '0644'))
620
+ expect(comp._component.configfiles).to include(Vanagon::Common::Pathname.configfile('place/to/put/thing1.pristine'))
628
621
  expect(comp._component.configfiles).not_to include(Vanagon::Common::Pathname.file('place/to/put/thing1'))
629
622
  end
630
623
  end
@@ -656,18 +649,40 @@ end" }
656
649
  end
657
650
 
658
651
  describe '#environment' do
652
+ before :each do
653
+ @comp = Vanagon::Component::DSL.new('env-test', {}, {})
654
+ end
655
+
656
+ before :example do
657
+ @path = {'PATH' => '/usr/local/bin'}
658
+ @alternate_path = {'PATH' => '/usr/bin'}
659
+ @cflags = {'CFLAGS' => '-I /usr/local/bin'}
660
+ @merged_env = @cflags.merge(@alternate_path)
661
+ end
662
+
659
663
  it 'adds an override to the environment for a component' do
660
- comp = Vanagon::Component::DSL.new('env-test', {}, {})
661
- comp.environment({'PATH' => '/usr/local/bin'})
662
- expect(comp._component.environment).to eq({'PATH' => '/usr/local/bin'})
664
+ @comp.environment(@path)
665
+ @path.each_pair do |key, value|
666
+ expect(@comp._component.environment[key]).to eq(value)
667
+ end
663
668
  end
664
669
 
665
670
  it 'merges against the existing environment' do
666
- comp = Vanagon::Component::DSL.new('env-test', {}, {})
667
- comp.environment({'PATH' => '/usr/local/bin'})
668
- comp.environment({'PATH' => '/usr/bin'})
669
- comp.environment({'CFLAGS' => '-I /usr/local/bin'})
670
- expect(comp._component.environment).to eq({'PATH' => '/usr/bin', 'CFLAGS' => '-I /usr/local/bin'})
671
+ # Set a value that should *NOT* be present
672
+ @comp.environment(@path)
673
+ # And then set two values that should
674
+ @comp.environment(@alternate_path)
675
+ @comp.environment(@cflags)
676
+
677
+ # Test that our canary doesn't exist
678
+ @path.each_pair do |key, value|
679
+ expect(@comp._component.environment[key]).to_not eq(value)
680
+ end
681
+
682
+ # And then validate our expected values
683
+ @merged_env.each_pair do |key, value|
684
+ expect(@comp._component.environment[key]).to eq(value)
685
+ end
671
686
  end
672
687
  end
673
688
 
@@ -43,17 +43,14 @@ describe Vanagon::Component::Rules do
43
43
 
44
44
  it "extracts the source" do
45
45
  component.extract_with = "/usr/bin/tar"
46
- expect(rule.recipe.first).to eq ": && /usr/bin/tar"
46
+ expect(rule.recipe.first).to eq "/usr/bin/tar"
47
47
  end
48
48
 
49
49
  it "sets environment variables before running the unpack steps" do
50
50
  component.extract_with = "/usr/bin/tar"
51
51
  component.environment = {"PATH" => "/opt/pl-build-tools/bin:$$PATH"}
52
52
  expect(rule.recipe.first).to eq(
53
- [
54
- "export PATH=\"/opt/pl-build-tools/bin:$$PATH\"",
55
- "/usr/bin/tar"
56
- ].join(" && ")
53
+ [ "/usr/bin/tar" ].join(" && ")
57
54
  )
58
55
  end
59
56
 
@@ -108,7 +105,6 @@ describe Vanagon::Component::Rules do
108
105
  expect(rule.recipe[1]).to eq(
109
106
  [
110
107
  "cd /foo/bar",
111
- ":",
112
108
  "./configure",
113
109
  "cmake .."
114
110
  ].join(" && \\\n")
@@ -121,7 +117,6 @@ describe Vanagon::Component::Rules do
121
117
  expect(rule.recipe[1]).to eq(
122
118
  [
123
119
  "cd /foo/bar",
124
- "export PATH=\"/opt/pl-build-tools/bin:$$PATH\"",
125
120
  "./configure",
126
121
  "cmake .."
127
122
  ].join(" && \\\n")
@@ -145,7 +140,6 @@ describe Vanagon::Component::Rules do
145
140
  expect(rule.recipe.first).to eq(
146
141
  [
147
142
  "cd /foo/bar",
148
- ":",
149
143
  "make",
150
144
  "make test",
151
145
  ].join(" && \\\n")
@@ -158,7 +152,6 @@ describe Vanagon::Component::Rules do
158
152
  expect(rule.recipe.first).to eq(
159
153
  [
160
154
  "cd /foo/bar",
161
- "export PATH=\"/opt/pl-build-tools/bin:$$PATH\"",
162
155
  "make",
163
156
  "make test"
164
157
  ].join(" && \\\n")
@@ -188,7 +181,6 @@ describe Vanagon::Component::Rules do
188
181
  expect(rule.recipe.first).to eq(
189
182
  [
190
183
  "cd /foo/bar",
191
- ":",
192
184
  "make cpplint",
193
185
  "make test",
194
186
  ].join(" && \\\n")
@@ -201,7 +193,6 @@ describe Vanagon::Component::Rules do
201
193
  expect(rule.recipe.first).to eq(
202
194
  [
203
195
  "cd /foo/bar",
204
- "export PATH=\"/opt/pl-build-tools/bin:$$PATH\"",
205
196
  "make cpplint",
206
197
  "make test"
207
198
  ].join(" && \\\n")
@@ -225,7 +216,6 @@ describe Vanagon::Component::Rules do
225
216
  expect(rule.recipe.first).to eq(
226
217
  [
227
218
  "cd /foo/bar",
228
- ":",
229
219
  "make install",
230
220
  "make reallyinstall",
231
221
  ].join(" && \\\n")
@@ -238,7 +228,6 @@ describe Vanagon::Component::Rules do
238
228
  expect(rule.recipe.first).to eq(
239
229
  [
240
230
  "cd /foo/bar",
241
- "export PATH=\"/opt/pl-build-tools/bin:$$PATH\"",
242
231
  "make install",
243
232
  "make reallyinstall"
244
233
  ].join(" && \\\n")
@@ -2,38 +2,63 @@ require 'vanagon/component'
2
2
 
3
3
  describe "Vanagon::Component" do
4
4
  describe "#get_environment" do
5
+ subject { Vanagon::Component.new('env-test', {}, {}) }
6
+
7
+ it "prints a deprecation warning to STDERR" do
8
+ expect { subject.get_environment }.to output(/deprecated/).to_stderr
9
+ end
10
+
5
11
  it "returns a makefile compatible environment" do
6
- comp = Vanagon::Component.new('env-test', {}, {})
7
- comp.environment = {'PATH' => '/usr/local/bin'}
8
- expect(comp.get_environment).to eq('export PATH="/usr/local/bin"')
12
+ subject.environment = {'PATH' => '/usr/local/bin'}
13
+ expect(subject.get_environment).to eq %(export PATH="/usr/local/bin")
9
14
  end
10
15
 
11
16
  it 'merges against the existing environment' do
12
- comp = Vanagon::Component.new('env-test', {}, {})
13
- comp.environment = {'PATH' => '/usr/bin', 'CFLAGS' => '-I /usr/local/bin'}
14
- expect(comp.get_environment).to eq('export PATH="/usr/bin" CFLAGS="-I /usr/local/bin"')
17
+ subject.environment = {'PATH' => '/usr/bin', 'CFLAGS' => '-I /usr/local/bin'}
18
+ expect(subject.get_environment).to eq %(export PATH="/usr/bin" CFLAGS="-I /usr/local/bin")
15
19
  end
16
20
 
17
21
  it 'returns : for an empty environment' do
18
- comp = Vanagon::Component.new('env-test', {}, {})
19
- expect(comp.get_environment).to eq(':')
22
+ expect(subject.get_environment).to eq %(: no environment variables defined)
20
23
  end
21
24
  end
22
25
 
23
26
  describe "#get_build_dir" do
24
- subject(:comp) do
27
+ subject do
25
28
  Vanagon::Component.new('build-dir-test', {}, {}).tap do |comp|
26
29
  comp.dirname = "build-dir-test"
27
30
  end
28
31
  end
29
32
 
30
33
  it "uses the dirname when no build_dir was set" do
31
- expect(comp.get_build_dir).to eq "build-dir-test"
34
+ expect(subject.get_build_dir).to eq "build-dir-test"
32
35
  end
33
36
 
34
37
  it "joins the dirname and the build dir when a build_dir was set" do
35
- comp.build_dir = "cmake-build"
36
- expect(comp.get_build_dir).to eq File.join("build-dir-test", "cmake-build")
38
+ subject.build_dir = "cmake-build"
39
+ expect(subject.get_build_dir).to eq File.join("build-dir-test", "cmake-build")
40
+ end
41
+ end
42
+
43
+ describe "#get_sources" do
44
+ before :each do
45
+ @workdir = Dir.mktmpdir
46
+ @file_name = 'fake_file.txt'
47
+ @fake_file = "file://spec/fixtures/files/#{@file_name}"
48
+ end
49
+
50
+ subject do
51
+ # Initialize a new instance of Vanagon::Component and define a
52
+ # new secondary source. We can now reason about this instance and
53
+ # test behavior for retrieving secondary sources.
54
+ Vanagon::Component.new('build-dir-test', {}, {}).tap do |comp|
55
+ comp.sources << OpenStruct.new(url: @fake_file)
56
+ end
57
+ end
58
+
59
+ it "copies secondary sources into the workdir" do
60
+ subject.get_sources(@workdir)
61
+ expect(File.exist?(File.join(@workdir, @file_name))).to be true
37
62
  end
38
63
  end
39
64
  end