bozo-scripts 0.1.6 → 0.1.7
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.
- data/LICENSE +18 -18
- data/VERSION +1 -1
- data/lib/bozo/compilers/msbuild.rb +279 -279
- data/lib/bozo/configuration.rb +154 -154
- data/lib/bozo/dependency_resolvers/bundler.rb +53 -53
- data/lib/bozo/dependency_resolvers/nuget.rb +85 -85
- data/lib/bozo/erubis_templating_coordinator.rb +127 -127
- data/lib/bozo/hooks/fxcop.rb +151 -151
- data/lib/bozo/hooks/git_commit_hashes.rb +11 -11
- data/lib/bozo/hooks/git_hub.rb +77 -0
- data/lib/bozo/hooks/git_tag_release.rb +22 -22
- data/lib/bozo/hooks/jenkins.rb +18 -0
- data/lib/bozo/hooks/teamcity.rb +91 -91
- data/lib/bozo/hooks/timing.rb +40 -40
- data/lib/bozo/packagers/nuget.rb +226 -226
- data/lib/bozo/packagers/rubygems.rb +23 -23
- data/lib/bozo/preparers/common_assembly_info.rb +34 -34
- data/lib/bozo/preparers/file_templating.rb +152 -152
- data/lib/bozo/publishers/file_copy.rb +82 -82
- data/lib/bozo/publishers/rubygems.rb +17 -17
- data/lib/bozo/test_runners/dotcover.rb +157 -157
- data/lib/bozo/test_runners/nunit.rb +130 -130
- data/lib/bozo/test_runners/runit.rb +34 -34
- data/lib/bozo/version.rb +4 -4
- data/lib/bozo_scripts.rb +28 -26
- metadata +27 -7
- checksums.yaml +0 -15
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
module Bozo::Hooks
|
|
2
|
-
|
|
3
|
-
class GitCommitHashes
|
|
4
|
-
|
|
5
|
-
def post_dependencies
|
|
6
|
-
env['GIT_HASH'] = `git log -1 --format="%h"`.strip
|
|
7
|
-
env['GIT_HASH_FULL'] = `git log -1 --format="%H"`.strip
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
end
|
|
11
|
-
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
class GitCommitHashes
|
|
4
|
+
|
|
5
|
+
def post_dependencies
|
|
6
|
+
env['GIT_HASH'] = `git log -1 --format="%h"`.strip
|
|
7
|
+
env['GIT_HASH_FULL'] = `git log -1 --format="%H"`.strip
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
|
|
12
12
|
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
# Hooks for notifying GitHub of the build
|
|
4
|
+
#
|
|
5
|
+
# The following env variables are required
|
|
6
|
+
# - BUILD_URL
|
|
7
|
+
# - BUILD_NUMBER
|
|
8
|
+
#
|
|
9
|
+
# with_hook :git_hub do |h|
|
|
10
|
+
# h.token '.....'
|
|
11
|
+
# h.owner 'zopaUK'
|
|
12
|
+
# h.repo 'bozo-scripts'
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
class GitHub
|
|
16
|
+
require 'net/http'
|
|
17
|
+
require 'json'
|
|
18
|
+
|
|
19
|
+
def pre_build
|
|
20
|
+
submit_notification(:pending, "Build #{build_number} pending")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def post_build
|
|
24
|
+
submit_notification(:success, "Build #{build_number} succeeded")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def failed_build
|
|
28
|
+
submit_notification(:failed, "Build #{build_number} failed")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def token(token)
|
|
32
|
+
@token = token
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def owner(owner)
|
|
36
|
+
@owner = owner
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def repo(repo)
|
|
40
|
+
@repo = repo
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def build_url
|
|
46
|
+
env['BUILD_URL']
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def build_number
|
|
50
|
+
env['BUILD_NUMBER']
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def submit_notification(state, description)
|
|
54
|
+
return unless build_server?
|
|
55
|
+
|
|
56
|
+
log_info "Notifying GitHub of #{state} - #{description} - #{build_url}"
|
|
57
|
+
|
|
58
|
+
commit = `git rev-parse HEAD`
|
|
59
|
+
|
|
60
|
+
uri = URI("https://api.github.com/repos/#{@owner}/#{@repo}/statuses/#{commit}")
|
|
61
|
+
header = {
|
|
62
|
+
'Content-Type' => 'application/json',
|
|
63
|
+
'Authorization' => "token #{@token}",
|
|
64
|
+
'User-Agent' => 'Bozo GitHub notifier'
|
|
65
|
+
}
|
|
66
|
+
data = { state: state, description: description, target_url: build_url}.to_json
|
|
67
|
+
|
|
68
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
69
|
+
http.use_ssl = true
|
|
70
|
+
http.post(uri.request_uri, data, header)
|
|
71
|
+
|
|
72
|
+
log_info "Notified GitHub of #{state} - #{description} - #{build_url}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
module Bozo::Hooks
|
|
2
|
-
|
|
3
|
-
# Hook to tag a git repository when a release is published from a build
|
|
4
|
-
# server.
|
|
5
|
-
class GitTagRelease
|
|
6
|
-
|
|
7
|
-
def post_publish
|
|
8
|
-
return unless build_server?
|
|
9
|
-
log_info "Tagging repository for release #{version}"
|
|
10
|
-
|
|
11
|
-
tag_name = "rel-#{version}"
|
|
12
|
-
|
|
13
|
-
if `git tag`.split("\n").include? tag_name
|
|
14
|
-
raise Bozo::ConfigurationError.new "The tag #{tag_name} already exists"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
execute_command :git, ['git', 'tag', tag_name]
|
|
18
|
-
execute_command :git, ['git', 'push', '--tags']
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
end
|
|
22
|
-
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
# Hook to tag a git repository when a release is published from a build
|
|
4
|
+
# server.
|
|
5
|
+
class GitTagRelease
|
|
6
|
+
|
|
7
|
+
def post_publish
|
|
8
|
+
return unless build_server?
|
|
9
|
+
log_info "Tagging repository for release #{version}"
|
|
10
|
+
|
|
11
|
+
tag_name = "rel-#{version}"
|
|
12
|
+
|
|
13
|
+
if `git tag`.split("\n").include? tag_name
|
|
14
|
+
raise Bozo::ConfigurationError.new "The tag #{tag_name} already exists"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
execute_command :git, ['git', 'tag', tag_name]
|
|
18
|
+
execute_command :git, ['git', 'push', '--tags']
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
23
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
class Jenkins
|
|
4
|
+
|
|
5
|
+
def pre_build
|
|
6
|
+
if Jenkins.hosted_in_jenkins?
|
|
7
|
+
env['BUILD_URL'] = ENV['BUILD_URL']
|
|
8
|
+
env['BUILD_NUMBER'] = ENV['BUILD_NUMBER']
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.hosted_in_jenkins?
|
|
13
|
+
not ENV['JENKINS_HOME'].nil?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
data/lib/bozo/hooks/teamcity.rb
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
module Bozo::Hooks
|
|
2
|
-
|
|
3
|
-
class Teamcity
|
|
4
|
-
|
|
5
|
-
include Bozo::ClassNameHelpers
|
|
6
|
-
|
|
7
|
-
def pre_compile
|
|
8
|
-
return unless Teamcity.hosted_in_teamcity?
|
|
9
|
-
log_pre_step :compile
|
|
10
|
-
|
|
11
|
-
puts "##teamcity[buildNumber '#{version}']"
|
|
12
|
-
# currently a general compiler which wraps everything. Once a compiler hook is added can distinguish
|
|
13
|
-
# each specific compiler
|
|
14
|
-
puts "##teamcity[compilationStarted compiler='Bozo']"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def post_compile
|
|
18
|
-
return unless Teamcity.hosted_in_teamcity?
|
|
19
|
-
puts "##teamcity[compilationFinished compiler='Bozo']"
|
|
20
|
-
log_post_step :compile
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def post_test
|
|
24
|
-
return unless Teamcity.hosted_in_teamcity?
|
|
25
|
-
|
|
26
|
-
report
|
|
27
|
-
report_dotnetcoverage
|
|
28
|
-
|
|
29
|
-
log_post_step :test
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def method_missing(method, *args)
|
|
33
|
-
if method.to_s =~ /^(pre|post)_(.+)/
|
|
34
|
-
send "log_#{$1}_step".to_sym, $2
|
|
35
|
-
else
|
|
36
|
-
super
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def respond_to?(method)
|
|
41
|
-
method.to_s =~ /^(pre|post)_(.+)/ or super
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Returns whether teamcity is hosting bozo
|
|
45
|
-
def self.hosted_in_teamcity?
|
|
46
|
-
not ENV['TEAMCITY_VERSION'].nil?
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
# Notifies teamcity of general reports such as test runner results
|
|
52
|
-
def report
|
|
53
|
-
report_types = [:nunit, :fxcop]
|
|
54
|
-
report_types.each do |type|
|
|
55
|
-
reports = report_files(File.join(Dir.pwd, "/temp"), type)
|
|
56
|
-
|
|
57
|
-
reports.each do |report|
|
|
58
|
-
puts "##teamcity[importData type='#{type}' path='#{report}']"
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Notifies teamcity of dotNetCoverage results
|
|
64
|
-
def report_dotnetcoverage
|
|
65
|
-
tool_types = [:dot_cover]
|
|
66
|
-
|
|
67
|
-
tool_types.each do |type|
|
|
68
|
-
reports = report_files(File.join(Dir.pwd, "/temp"), type)
|
|
69
|
-
|
|
70
|
-
reports.each do |report|
|
|
71
|
-
tool_name = to_class_name(type).downcase
|
|
72
|
-
puts "##teamcity[importData type='dotNetCoverage' tool='#{tool_name}' path='#{report}']"
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def log_pre_step(step)
|
|
78
|
-
puts "##teamcity[progressStart 'Pre #{step}']" if Teamcity.hosted_in_teamcity?
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def log_post_step(step)
|
|
82
|
-
puts "##teamcity[progressEnd 'Post #{step}']" if Teamcity.hosted_in_teamcity?
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def report_files(path, type)
|
|
86
|
-
files = File.expand_path(File.join(path, "/**/*-#{to_class_name(type)}-report.xml"))
|
|
87
|
-
Dir[files]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
class Teamcity
|
|
4
|
+
|
|
5
|
+
include Bozo::ClassNameHelpers
|
|
6
|
+
|
|
7
|
+
def pre_compile
|
|
8
|
+
return unless Teamcity.hosted_in_teamcity?
|
|
9
|
+
log_pre_step :compile
|
|
10
|
+
|
|
11
|
+
puts "##teamcity[buildNumber '#{version}']"
|
|
12
|
+
# currently a general compiler which wraps everything. Once a compiler hook is added can distinguish
|
|
13
|
+
# each specific compiler
|
|
14
|
+
puts "##teamcity[compilationStarted compiler='Bozo']"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def post_compile
|
|
18
|
+
return unless Teamcity.hosted_in_teamcity?
|
|
19
|
+
puts "##teamcity[compilationFinished compiler='Bozo']"
|
|
20
|
+
log_post_step :compile
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def post_test
|
|
24
|
+
return unless Teamcity.hosted_in_teamcity?
|
|
25
|
+
|
|
26
|
+
report
|
|
27
|
+
report_dotnetcoverage
|
|
28
|
+
|
|
29
|
+
log_post_step :test
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def method_missing(method, *args)
|
|
33
|
+
if method.to_s =~ /^(pre|post)_(.+)/
|
|
34
|
+
send "log_#{$1}_step".to_sym, $2
|
|
35
|
+
else
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def respond_to?(method)
|
|
41
|
+
method.to_s =~ /^(pre|post)_(.+)/ or super
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns whether teamcity is hosting bozo
|
|
45
|
+
def self.hosted_in_teamcity?
|
|
46
|
+
not ENV['TEAMCITY_VERSION'].nil?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Notifies teamcity of general reports such as test runner results
|
|
52
|
+
def report
|
|
53
|
+
report_types = [:nunit, :fxcop]
|
|
54
|
+
report_types.each do |type|
|
|
55
|
+
reports = report_files(File.join(Dir.pwd, "/temp"), type)
|
|
56
|
+
|
|
57
|
+
reports.each do |report|
|
|
58
|
+
puts "##teamcity[importData type='#{type}' path='#{report}']"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Notifies teamcity of dotNetCoverage results
|
|
64
|
+
def report_dotnetcoverage
|
|
65
|
+
tool_types = [:dot_cover]
|
|
66
|
+
|
|
67
|
+
tool_types.each do |type|
|
|
68
|
+
reports = report_files(File.join(Dir.pwd, "/temp"), type)
|
|
69
|
+
|
|
70
|
+
reports.each do |report|
|
|
71
|
+
tool_name = to_class_name(type).downcase
|
|
72
|
+
puts "##teamcity[importData type='dotNetCoverage' tool='#{tool_name}' path='#{report}']"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def log_pre_step(step)
|
|
78
|
+
puts "##teamcity[progressStart 'Pre #{step}']" if Teamcity.hosted_in_teamcity?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def log_post_step(step)
|
|
82
|
+
puts "##teamcity[progressEnd 'Post #{step}']" if Teamcity.hosted_in_teamcity?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def report_files(path, type)
|
|
86
|
+
files = File.expand_path(File.join(path, "/**/*-#{to_class_name(type)}-report.xml"))
|
|
87
|
+
Dir[files]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
92
|
end
|
data/lib/bozo/hooks/timing.rb
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
module Bozo::Hooks
|
|
2
|
-
|
|
3
|
-
class Timing
|
|
4
|
-
|
|
5
|
-
def initialize
|
|
6
|
-
@timings = {}
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def print_timings
|
|
10
|
-
puts ''
|
|
11
|
-
@timings.each do |stage, times|
|
|
12
|
-
puts format_timing(stage, times).bright.color(stage == :build ? :cyan : :black)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def format_timing(stage, args)
|
|
17
|
-
time_taken = (args[:post] - args[:pre]).round(1)
|
|
18
|
-
"#{stage.to_s.capitalize.ljust(14)} #{time_taken.to_s.rjust(5)}s"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def record(stage, point)
|
|
22
|
-
@timings[stage] ||= {}
|
|
23
|
-
@timings[stage][point] = Time.now
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def method_missing(method, *args)
|
|
27
|
-
if method.to_s =~ /^(pre|post)_(.+)/
|
|
28
|
-
record $2.to_sym, $1.to_sym
|
|
29
|
-
print_timings if $1 == 'post' and $2 == 'build'
|
|
30
|
-
else
|
|
31
|
-
super
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def respond_to?(method)
|
|
36
|
-
method.to_s =~ /^(pre|post)_(.+)/ or super
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
|
|
1
|
+
module Bozo::Hooks
|
|
2
|
+
|
|
3
|
+
class Timing
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@timings = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def print_timings
|
|
10
|
+
puts ''
|
|
11
|
+
@timings.each do |stage, times|
|
|
12
|
+
puts format_timing(stage, times).bright.color(stage == :build ? :cyan : :black)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def format_timing(stage, args)
|
|
17
|
+
time_taken = (args[:post] - args[:pre]).round(1)
|
|
18
|
+
"#{stage.to_s.capitalize.ljust(14)} #{time_taken.to_s.rjust(5)}s"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def record(stage, point)
|
|
22
|
+
@timings[stage] ||= {}
|
|
23
|
+
@timings[stage][point] = Time.now
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def method_missing(method, *args)
|
|
27
|
+
if method.to_s =~ /^(pre|post)_(.+)/
|
|
28
|
+
record $2.to_sym, $1.to_sym
|
|
29
|
+
print_timings if $1 == 'post' and $2 == 'build'
|
|
30
|
+
else
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def respond_to?(method)
|
|
36
|
+
method.to_s =~ /^(pre|post)_(.+)/ or super
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
41
|
end
|
data/lib/bozo/packagers/nuget.rb
CHANGED
|
@@ -1,226 +1,226 @@
|
|
|
1
|
-
require 'nokogiri'
|
|
2
|
-
|
|
3
|
-
module Bozo::Packagers
|
|
4
|
-
|
|
5
|
-
class Nuget
|
|
6
|
-
|
|
7
|
-
def initialize
|
|
8
|
-
@libraries = []
|
|
9
|
-
@executables = []
|
|
10
|
-
@websites = []
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def destination(destination)
|
|
14
|
-
@destination = destination
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def library(project)
|
|
18
|
-
@libraries << LibraryPackage.new(project, self)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def executable(project)
|
|
22
|
-
@executables << ExecutablePackage.new(project)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def website(project)
|
|
26
|
-
@websites << WebsitePackage.new(project)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def required_tools
|
|
30
|
-
:nuget
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def project_url(url)
|
|
34
|
-
@project_url = url
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def license_url(url)
|
|
38
|
-
@license_url = url
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def author(author)
|
|
42
|
-
@author = author
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def to_s
|
|
46
|
-
"Publish projects with nuget #{@libraries | @executables | @websites} to #{@destination}"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def execute
|
|
50
|
-
@libraries.each {|project| package project}
|
|
51
|
-
@executables.each {|project| package project}
|
|
52
|
-
@websites.each {|project| package project}
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Returns the version that the package should be given.
|
|
56
|
-
def package_version
|
|
57
|
-
# If running on a build server then it is a real release, otherwise it is
|
|
58
|
-
# a preview release and the version should reflect that.
|
|
59
|
-
if build_server?
|
|
60
|
-
version
|
|
61
|
-
else
|
|
62
|
-
"#{version}-pre#{env['GIT_HASH']}"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
private
|
|
67
|
-
|
|
68
|
-
def package(project)
|
|
69
|
-
spec_path = generate_specification(project)
|
|
70
|
-
create_package(project.name, spec_path, true)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def generate_specification(project)
|
|
74
|
-
log_debug "Generating specification for #{project.name}"
|
|
75
|
-
builder = Nokogiri::XML::Builder.new do |doc|
|
|
76
|
-
doc.package(:xmlns => "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd") do
|
|
77
|
-
doc.metadata do
|
|
78
|
-
doc.id project.name
|
|
79
|
-
doc.version_ package_version
|
|
80
|
-
doc.authors @author
|
|
81
|
-
doc.description project.name
|
|
82
|
-
doc.projectUrl @project_url
|
|
83
|
-
doc.licenseUrl @license_url
|
|
84
|
-
doc.dependencies do
|
|
85
|
-
project.dependencies.each do |dep|
|
|
86
|
-
doc.dependency(dep)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
doc.files do
|
|
91
|
-
project.files.each do |file|
|
|
92
|
-
doc.file(file)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
spec_path = File.expand_path(File.join('temp', 'nuget', "#{project.name}.nuspec"))
|
|
98
|
-
FileUtils.mkdir_p File.dirname(spec_path)
|
|
99
|
-
File.open(spec_path, 'w+') {|f| f.write(builder.to_xml)}
|
|
100
|
-
spec_path
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def create_package(project, spec_path, omit_analysis = false)
|
|
104
|
-
args = []
|
|
105
|
-
|
|
106
|
-
dist_dir = File.expand_path(File.join('dist', 'nuget'))
|
|
107
|
-
|
|
108
|
-
args << File.expand_path(File.join('build', 'tools', 'nuget', 'NuGet.exe'))
|
|
109
|
-
args << 'pack'
|
|
110
|
-
args << "\"#{spec_path}\""
|
|
111
|
-
args << '-OutputDirectory'
|
|
112
|
-
args << "\"#{dist_dir}\""
|
|
113
|
-
args << '-NoPackageAnalysis' if omit_analysis
|
|
114
|
-
|
|
115
|
-
# Ensure the directory is there because Nuget won't make it
|
|
116
|
-
FileUtils.mkdir_p dist_dir
|
|
117
|
-
|
|
118
|
-
log_debug "Creating nuget package for #{project}"
|
|
119
|
-
|
|
120
|
-
execute_command :nuget, args
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
private
|
|
126
|
-
|
|
127
|
-
class ExecutablePackage
|
|
128
|
-
|
|
129
|
-
def initialize(project)
|
|
130
|
-
@name = project
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def name
|
|
134
|
-
@name
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def dependencies
|
|
138
|
-
[]
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def files
|
|
142
|
-
[{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', '*.*')).gsub(/\//, '\\'), :target => 'exe'}]
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
class LibraryPackage
|
|
148
|
-
|
|
149
|
-
def initialize(project, nuget)
|
|
150
|
-
@name = project
|
|
151
|
-
@nuget = nuget
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def name
|
|
155
|
-
@name
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def dependencies
|
|
159
|
-
project_reference_dependencies + nuget_dependencies
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def files
|
|
163
|
-
%w{dll pdb xml}.map do |extension|
|
|
164
|
-
{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', "#{@name}.#{extension}")).gsub(/\//, '\\'), :target => 'lib'}
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
private
|
|
169
|
-
|
|
170
|
-
def project_reference_dependencies
|
|
171
|
-
doc = Nokogiri::XML(File.open(project_file))
|
|
172
|
-
|
|
173
|
-
doc.xpath('//proj:Project/proj:ItemGroup/proj:ProjectReference/proj:Name', {"proj" => "http://schemas.microsoft.com/developer/msbuild/2003"}).map do |node|
|
|
174
|
-
{:id => node.text, :version => "[#{@nuget.package_version}]"}
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# get dependencies from packages.config
|
|
179
|
-
def nuget_dependencies
|
|
180
|
-
package_file = packages_file
|
|
181
|
-
return [] unless File.exist? package_file
|
|
182
|
-
|
|
183
|
-
doc = Nokogiri::XML(File.open(package_file))
|
|
184
|
-
|
|
185
|
-
doc.xpath('//packages/package').map do |node|
|
|
186
|
-
{:id => node[:id], :version => "[#{node[:version]}]"}
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def packages_file
|
|
191
|
-
find_file_in_project 'packages.config'
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def project_file
|
|
195
|
-
find_file_in_project "#{@name}.csproj"
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def find_file_in_project(file_name)
|
|
199
|
-
file = File.expand_path(File.join('src', 'csharp', @name, file_name))
|
|
200
|
-
file = File.expand_path(File.join('test', 'csharp', @name, file_name)) unless File.exist? file
|
|
201
|
-
file
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
class WebsitePackage
|
|
207
|
-
|
|
208
|
-
def initialize(project)
|
|
209
|
-
@name = project
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def name
|
|
213
|
-
@name
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def dependencies
|
|
217
|
-
[]
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def files
|
|
221
|
-
[{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', '*.*')).gsub(/\//, '\\'), :target => 'website'}]
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
end
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
|
|
3
|
+
module Bozo::Packagers
|
|
4
|
+
|
|
5
|
+
class Nuget
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@libraries = []
|
|
9
|
+
@executables = []
|
|
10
|
+
@websites = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def destination(destination)
|
|
14
|
+
@destination = destination
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def library(project)
|
|
18
|
+
@libraries << LibraryPackage.new(project, self)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def executable(project)
|
|
22
|
+
@executables << ExecutablePackage.new(project)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def website(project)
|
|
26
|
+
@websites << WebsitePackage.new(project)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def required_tools
|
|
30
|
+
:nuget
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def project_url(url)
|
|
34
|
+
@project_url = url
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def license_url(url)
|
|
38
|
+
@license_url = url
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def author(author)
|
|
42
|
+
@author = author
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def to_s
|
|
46
|
+
"Publish projects with nuget #{@libraries | @executables | @websites} to #{@destination}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def execute
|
|
50
|
+
@libraries.each {|project| package project}
|
|
51
|
+
@executables.each {|project| package project}
|
|
52
|
+
@websites.each {|project| package project}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns the version that the package should be given.
|
|
56
|
+
def package_version
|
|
57
|
+
# If running on a build server then it is a real release, otherwise it is
|
|
58
|
+
# a preview release and the version should reflect that.
|
|
59
|
+
if build_server?
|
|
60
|
+
version
|
|
61
|
+
else
|
|
62
|
+
"#{version}-pre#{env['GIT_HASH']}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def package(project)
|
|
69
|
+
spec_path = generate_specification(project)
|
|
70
|
+
create_package(project.name, spec_path, true)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def generate_specification(project)
|
|
74
|
+
log_debug "Generating specification for #{project.name}"
|
|
75
|
+
builder = Nokogiri::XML::Builder.new do |doc|
|
|
76
|
+
doc.package(:xmlns => "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd") do
|
|
77
|
+
doc.metadata do
|
|
78
|
+
doc.id project.name
|
|
79
|
+
doc.version_ package_version
|
|
80
|
+
doc.authors @author
|
|
81
|
+
doc.description project.name
|
|
82
|
+
doc.projectUrl @project_url
|
|
83
|
+
doc.licenseUrl @license_url
|
|
84
|
+
doc.dependencies do
|
|
85
|
+
project.dependencies.each do |dep|
|
|
86
|
+
doc.dependency(dep)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
doc.files do
|
|
91
|
+
project.files.each do |file|
|
|
92
|
+
doc.file(file)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
spec_path = File.expand_path(File.join('temp', 'nuget', "#{project.name}.nuspec"))
|
|
98
|
+
FileUtils.mkdir_p File.dirname(spec_path)
|
|
99
|
+
File.open(spec_path, 'w+') {|f| f.write(builder.to_xml)}
|
|
100
|
+
spec_path
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def create_package(project, spec_path, omit_analysis = false)
|
|
104
|
+
args = []
|
|
105
|
+
|
|
106
|
+
dist_dir = File.expand_path(File.join('dist', 'nuget'))
|
|
107
|
+
|
|
108
|
+
args << File.expand_path(File.join('build', 'tools', 'nuget', 'NuGet.exe'))
|
|
109
|
+
args << 'pack'
|
|
110
|
+
args << "\"#{spec_path}\""
|
|
111
|
+
args << '-OutputDirectory'
|
|
112
|
+
args << "\"#{dist_dir}\""
|
|
113
|
+
args << '-NoPackageAnalysis' if omit_analysis
|
|
114
|
+
|
|
115
|
+
# Ensure the directory is there because Nuget won't make it
|
|
116
|
+
FileUtils.mkdir_p dist_dir
|
|
117
|
+
|
|
118
|
+
log_debug "Creating nuget package for #{project}"
|
|
119
|
+
|
|
120
|
+
execute_command :nuget, args
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
class ExecutablePackage
|
|
128
|
+
|
|
129
|
+
def initialize(project)
|
|
130
|
+
@name = project
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def name
|
|
134
|
+
@name
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def dependencies
|
|
138
|
+
[]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def files
|
|
142
|
+
[{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', '*.*')).gsub(/\//, '\\'), :target => 'exe'}]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class LibraryPackage
|
|
148
|
+
|
|
149
|
+
def initialize(project, nuget)
|
|
150
|
+
@name = project
|
|
151
|
+
@nuget = nuget
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def name
|
|
155
|
+
@name
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def dependencies
|
|
159
|
+
project_reference_dependencies + nuget_dependencies
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def files
|
|
163
|
+
%w{dll pdb xml}.map do |extension|
|
|
164
|
+
{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', "#{@name}.#{extension}")).gsub(/\//, '\\'), :target => 'lib'}
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
def project_reference_dependencies
|
|
171
|
+
doc = Nokogiri::XML(File.open(project_file))
|
|
172
|
+
|
|
173
|
+
doc.xpath('//proj:Project/proj:ItemGroup/proj:ProjectReference/proj:Name', {"proj" => "http://schemas.microsoft.com/developer/msbuild/2003"}).map do |node|
|
|
174
|
+
{:id => node.text, :version => "[#{@nuget.package_version}]"}
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# get dependencies from packages.config
|
|
179
|
+
def nuget_dependencies
|
|
180
|
+
package_file = packages_file
|
|
181
|
+
return [] unless File.exist? package_file
|
|
182
|
+
|
|
183
|
+
doc = Nokogiri::XML(File.open(package_file))
|
|
184
|
+
|
|
185
|
+
doc.xpath('//packages/package').map do |node|
|
|
186
|
+
{:id => node[:id], :version => "[#{node[:version]}]"}
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def packages_file
|
|
191
|
+
find_file_in_project 'packages.config'
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def project_file
|
|
195
|
+
find_file_in_project "#{@name}.csproj"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def find_file_in_project(file_name)
|
|
199
|
+
file = File.expand_path(File.join('src', 'csharp', @name, file_name))
|
|
200
|
+
file = File.expand_path(File.join('test', 'csharp', @name, file_name)) unless File.exist? file
|
|
201
|
+
file
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
class WebsitePackage
|
|
207
|
+
|
|
208
|
+
def initialize(project)
|
|
209
|
+
@name = project
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def name
|
|
213
|
+
@name
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def dependencies
|
|
217
|
+
[]
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def files
|
|
221
|
+
[{:src => File.expand_path(File.join('temp', 'msbuild', @name, '**', '*.*')).gsub(/\//, '\\'), :target => 'website'}]
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
end
|