vanagon 0.9.3 → 0.10.0

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