azbuild 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 912af354939208cdcaa18b47b7b566da75ac0107
4
+ data.tar.gz: e455f03afb79053387f59ca0522908aac607f4e2
5
+ SHA512:
6
+ metadata.gz: a02e03e702ddbcae033201c29545fafe13728a77ce5c17de2363a8fe1c2f8b9114aeedaca37dc90bbd730ddaa1e0a6a70d5a51f0bbdc403fa7474ad9c8813ac5
7
+ data.tar.gz: 818145206931035c8176708d3f43fd65a6b2c58e5f8031ddd2f1cdc72d5154ac1654642626cbf4745e3daff5e90148f76d9e53c9b03dfc5c02d2329f7255ca68
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ azbuild
2
+ ========
3
+
4
+ .Net solutions that are built using the ruby gem albacore and use semantic versioning via semver have verbosity and bloated rake files with some boiler plate that can be reduced and simplified. There are also configuration transforms that can be applied per deployable environment before projects are built. This gem azbuild provides those functions.
5
+
6
+ The gem also simplifies ruby version and gem dependencies by bootstrapping itself to detect and install right gem versions. This may soon chnage to use bundler in future.
7
+
8
+ <b>Note: </b>azbuild is the next evolution of <b>azdeploy</b> gem that is available on http://rubygems.org
9
+
10
+ <b>Where do configuration values come from?</b>
11
+
12
+ Currently, configuration key value pairs for specific transforms are stored and retrived from an Azure Table using azure ruby gem. More transforms can be added as well as other configuration sources
13
+
14
+ <b>How to use the gem</b>
15
+
16
+ azbuild is in development and you'll need to use azdeploy until azbuild development is complete.
17
+
18
+ To start using azdeploy,
19
+
20
+ 1. install Ruby version 2.0.0p481
21
+ 2. install azdeploy from http://rubygems.org
22
+ 3. require the azdeploy gem in a blank rake script
23
+ 4. run rake script
24
+
25
+ Running the rake script from above will kick-off the install sequence and install all requisite gems. Follow prompts and take appropriate actions like restarting console.
26
+
27
+ A typical build would perform the following steps:
28
+
29
+ 1. clean solution build output folders
30
+ 2. transform configuration
31
+ 3. restore nuget packages
32
+ 4. build the solution
33
+ 5. run unit tests
34
+ 6. copy build output to specified folders
35
+ 7. create nuget packages as specified and copy to artifacts folders
36
+ 8. run publish where required (web projects)
37
+
38
+ Few examples of tasks and their usage is as follows:
39
+
40
+ ```
41
+ desc 'Prepares the working directory for a new build'
42
+ task :clean do
43
+ cleantask(BUILD_PATHS)
44
+ end
45
+
46
+ desc 'Transform Configuration'
47
+ task :transform_config do
48
+ Transform.new.transform([''])
49
+ end
50
+
51
+ desc 'restores missing packages'
52
+ task :restore do
53
+ restore_nuget(NUGET) # path of nuget exe
54
+ end
55
+
56
+ desc 'Only compiles the application.'
57
+ msbuild :build do |msb|
58
+ msb.targets :Clean, :Build
59
+ clean_build(msb, "src/#{PRODUCT}.sln")
60
+ end
61
+
62
+ desc "Publishes."
63
+ msbuild :publish do |msb|
64
+ msb.targets :Publish
65
+ clean_build(msb, "src/#{PRODUCT}.sln")
66
+ end
67
+
68
+ desc 'Running rake for each sub project'
69
+ task :package do
70
+
71
+ end
72
+
73
+ desc 'Copies build output to designated folders.'
74
+ task :copy_output do
75
+ outputs.each { |name, filter|
76
+ copy_output_files File.join(BUILD_PATHS[:src], name), filter, File.join(BUILD_PATHS[:output], 'net-4.5')
77
+ }
78
+ end
79
+
80
+ desc 'Cleans, versions, compiles the application and generates build_output.'
81
+ task :compile => [:build, :tests, :copy_output]
82
+
83
+ desc '**Default**, compiles and runs tests'
84
+ task :default => [:clean, :transform_config, :restore, :compile, :package, :publish]
85
+
86
+ ```
87
+
88
+ Instructions for azbuild when it's ready:
89
+
90
+ 1. Install latest version of Ruby
91
+ 2. Install the gem from http://rubygems.org
92
+ 3. Run bundle update
93
+ 4. require gem in a rake script and start using available methods
data/azbuild.gemspec ADDED
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'azbuild'
3
+ s.version = '1.0.0'
4
+ s.date = '2016-08-14'
5
+ s.summary = 'Setup and scripting support for .Net project builds'
6
+ s.description = 'Build, Configuration and Deployment Gem for .Net Solutions'
7
+ s.authors = ['Suresh Batta']
8
+ s.email = 'subatta@hotmail.com'
9
+ s.files = Dir['{lib,test}/**/*'] + ['azbuild.gemspec', 'README.md', 'rakefile.rb']
10
+ s.homepage = 'http://rubygems.org/gems/azbuild'
11
+ s.license = 'MIT'
12
+ end
data/lib/azbuild.rb ADDED
@@ -0,0 +1,24 @@
1
+ require_relative 'string_extensions.rb'
2
+ require_relative 'install.rb'
3
+ require_relative 'build.rb'
4
+ require_relative 'versioning.rb'
5
+ require_relative 'package.rb'
6
+ require_relative 'semver_extensions'
7
+
8
+ # installation
9
+ installers = [
10
+ 'ruby', 'gems'
11
+ ]
12
+
13
+ installers.each { |method|
14
+ exit if !send("check_#{method}")
15
+ }
16
+
17
+ #require 'rubygems'
18
+ require 'nokogiri'
19
+
20
+ # includes for rake build
21
+ include FileTest
22
+ require 'albacore'
23
+ require 'semver'
24
+ require 'json'
data/lib/build.rb ADDED
@@ -0,0 +1,92 @@
1
+
2
+ def copy_output_files fromDir, filePattern, outDir
3
+ FileUtils.mkdir_p outDir unless exists?(outDir)
4
+ Dir.glob(File.join(fromDir, filePattern)){|file|
5
+ copy(file, outDir) if File.file?(file)
6
+ }
7
+ end
8
+
9
+ def project_outputs props
10
+ props[:projects].map{ |p| "src/#{p}/bin/#{BUILD_CONFIG}/#{p}.dll" }.
11
+ concat( props[:projects].map{ |p| "src/#{p}/bin/#{BUILD_CONFIG}/#{p}.exe" } ).
12
+ find_all{ |path| exists?(path) }
13
+ end
14
+
15
+ def add_files stage, what_dlls, nuspec, folder='lib'
16
+ [['net35', 'net-3.5'], ['net40', 'net-4.0'], ['net45', 'net-4.5']].each{|fw|
17
+ takeFrom = File.join(stage, fw[1], what_dlls)
18
+ Dir.glob(takeFrom).each do |f|
19
+ nuspec.file(f.gsub("/", "\\"), "#{folder}\\#{fw[0]}")
20
+ end
21
+ }
22
+ end
23
+
24
+ def commit_data
25
+ begin
26
+ commit = `git rev-parse --short HEAD`.chomp()[0,6]
27
+ git_date = `git log -1 --date=iso --pretty=format:%ad`
28
+ commit_date = DateTime.parse( git_date ).strftime("%Y-%m-%d %H%M%S")
29
+ rescue Exception => e
30
+ puts e.inspect
31
+ commit = (ENV['BUILD_VCS_NUMBER'] || "000000")[0,6]
32
+ commit_date = Time.new.strftime("%Y-%m-%d %H%M%S")
33
+ end
34
+ [commit, commit_date]
35
+ end
36
+
37
+ def waitfor &block
38
+ checks = 0
39
+
40
+ until block.call || checks >10
41
+ sleep 0.5
42
+ checks += 1
43
+ end
44
+
45
+ raise 'Waitfor timeout expired. Make sure that you aren\'t ' \
46
+ 'running something from the build output folders, or that you ' \
47
+ 'have browsed to it through Explorer.'.red if checks > 10
48
+ end
49
+
50
+ def cleantask props
51
+
52
+ if props.has_key?(:output) && File.directory?(props[:output])
53
+ FileUtils.rm_rf props[:output]
54
+ waitfor { !exists?(props[:output]) }
55
+ end
56
+
57
+ if props.has_key?(:artifacts) && File.directory?(props[:artifacts])
58
+ FileUtils.rm_rf props[:artifacts]
59
+ waitfor { !exists?(props[:artifacts]) }
60
+ end
61
+
62
+ if props.has_key?(:output)
63
+ Dir.mkdir props[:output]
64
+ end
65
+ if props.has_key?(:artifacts)
66
+ Dir.mkdir props[:artifacts]
67
+ end
68
+ end
69
+
70
+ def run_vsconsole_tests settings, params = nil, assemblies = nil
71
+
72
+ raise 'Settings file name is required' if settings.nil?
73
+
74
+ if assemblies.nil?
75
+ assemblies = FileList["**/#{OUTPUT_PATH}/*.Tests.dll"]
76
+ filelist = assemblies.map { |assembly| File.join(Dir.pwd, assembly)}
77
+ end
78
+
79
+ test_runner :tests do |tests|
80
+ tests.files = filelist
81
+ tests.exe = 'C:/Program Files (x86)/Microsoft Visual Studio 14.0/Common7/IDE/CommonExtensions/Microsoft/TestWindow/VSTest.console.exe'
82
+ if (params != nil)
83
+ params.each { | p |
84
+ tests.add_parameter p
85
+ }
86
+ end
87
+ tests.add_parameter '/InIsolation'
88
+ tests.add_parameter '/Logger:trx'
89
+ tests.add_parameter "/Settings:#{Dir.pwd}/#{settings}.runsettings"
90
+ end
91
+
92
+ end
data/lib/install.rb ADDED
@@ -0,0 +1,74 @@
1
+ require 'net/http'
2
+
3
+ $ruby_version_map = {
4
+ '2.3.1-p112' => {
5
+ :gems => {
6
+ 'nokogiri' => '1.6.8',
7
+ 'albacore' => '2.6.1',
8
+ 'semver2' => '3.4.2',
9
+ 'nuget' => '3.2.0'
10
+ }
11
+ }
12
+ }
13
+
14
+ $selected_version = {}
15
+
16
+ # Ruby version check
17
+ def check_ruby
18
+ puts "Checking ruby version...".bg_green.white if (ENV['debug'])
19
+
20
+ # check if expected ruby version exists. If not download and install ruby
21
+ rubyVersion = "#{RUBY_VERSION}"
22
+ localVersion = "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
23
+ expectedVersions = $ruby_version_map.keys
24
+ if (!rubyVersion.nil? && !expectedVersions.include?(localVersion))
25
+ puts "Uninstall incompatible version of ruby: #{localVersion} and " \
26
+ "install any one of these Ruby versions: #{expectedVersions}. " \
27
+ "Then Restart rake. Goto http://rubyinstaller.org/downloads/".red
28
+ return false
29
+ else
30
+ puts "#{localVersion} is the expected version.".green if (ENV['debug'])
31
+ end
32
+
33
+ $selected_version = $ruby_version_map[localVersion]
34
+ if ($selected_version != nil)
35
+ puts "Ruby version found: #{localVersion}".green if (ENV['debug'])
36
+ puts 'Ruby ok'.green if (ENV['debug'])
37
+ end
38
+ return true
39
+ end
40
+
41
+ # check and install required gems
42
+ def check_gems
43
+ puts 'Checking required gems...'.bg_green.white if (ENV['debug'])
44
+ $selected_version[:gems].each {|key, value|
45
+ if !gem_exists(key, value)
46
+ begin
47
+ puts "Installing missing gem: #{key}".bg_green.white
48
+ cmd = "gem install #{key} -v #{value}"
49
+ cmdoutput = `#{cmd}`
50
+ puts cmdoutput.bg_green.white
51
+ rescue
52
+ puts 'gem install failed'.red
53
+ puts $!
54
+ return false # don't continue if even one gem install fails
55
+ end
56
+ else
57
+ puts "Gem #{key}, #{value} exists".green if (ENV['debug'])
58
+ end
59
+ }
60
+ # all gems installed
61
+ return true
62
+ end
63
+
64
+ # Checks if a gem of a version exists
65
+ def gem_exists(name, version)
66
+ begin
67
+ gem name, "=#{version}"
68
+ rescue Gem::LoadError
69
+ puts "failed to load gem #{name} -v #{version}".red
70
+ Gem.clear_paths
71
+ return false
72
+ end
73
+ return true
74
+ end
data/lib/package.rb ADDED
@@ -0,0 +1,76 @@
1
+ def nuget_pack id, config, artifact_path
2
+ require 'albacore/task_types/nugets_pack'
3
+
4
+ p = Albacore::NugetsPack::Config.new
5
+
6
+ p.configuration = BUILD_CONFIG
7
+
8
+ if !config.has_key? :project || config[:project] == ''
9
+ raise 'At least one project is required to build'.red
10
+ end
11
+
12
+ p.files = config[:project]
13
+
14
+ if config.has_key? :nuspec && config[:nuspec] != ''
15
+ p.nuspec = config[:nuspec]
16
+ end
17
+
18
+ p.out = artifact_path
19
+
20
+ p.with_metadata do |m|
21
+ m.id = id
22
+ m.title = PRODUCT
23
+ m.description = PRODUCT_DESCRIPTION
24
+ m.authors = COMPANY
25
+ m.version = config[:version]
26
+ if config.has_key? :dependencies
27
+ config[:dependencies].each { |name, version|
28
+ m.add_dependency name, version
29
+ }
30
+ end
31
+ end
32
+
33
+ p.target = config[:target_framework]
34
+ p.with_package do |p|
35
+ if config.has_key? :files
36
+ config[:files].each { |folder, files|
37
+ files.each{ |file|
38
+ p.add_file file, folder
39
+ }
40
+ }
41
+ end
42
+ end
43
+
44
+ p.gen_symbols
45
+ p.nuget_gem_exe
46
+ #p.leave_nuspec
47
+
48
+ Albacore::NugetsPack::ProjectTask.new(p.opts).execute
49
+ end
50
+
51
+ def nuget_content nuget_name, path, dotnet_ver
52
+
53
+ content = {}
54
+
55
+ metadata = SemVerMetadata.new ".semver/#{nuget_name}.semver"
56
+
57
+ content[:files] = {}
58
+ content[:files]['lib'] = metadata.files
59
+
60
+ file_names = metadata.assemblies.map{ |x|
61
+ "#{path}/#{x}"
62
+ }
63
+ assemblies = []
64
+ file_names.each{ |file|
65
+ assemblies.concat(file.expand_with(['dll','pdb','xml']))
66
+ }
67
+ content[:files]['lib'].concat assemblies
68
+
69
+ content[:dependencies] = metadata.depends
70
+
71
+ content[:version] = read_versions[nuget_name][:nuget_version]
72
+ content[:target_framework] = dotnet_ver
73
+
74
+ content
75
+ end
76
+
@@ -0,0 +1,51 @@
1
+ class SemVerMetadata
2
+
3
+ def initialize file
4
+ @assemblies = []
5
+ @files = []
6
+ @depends = {}
7
+ parse file
8
+ end
9
+
10
+ def assemblies
11
+ @assemblies
12
+ end
13
+
14
+ def files
15
+ @files
16
+ end
17
+
18
+ def depends
19
+ @depends
20
+ end
21
+
22
+ def parse file
23
+
24
+ semver = SemVer.new
25
+ semver.load file
26
+
27
+ return if semver.metadata == ''
28
+
29
+ parts = semver.metadata.split('|')
30
+
31
+ return if parts.length < 1
32
+
33
+ proj_lines = parts[0].split(',')
34
+ proj_lines.each {|line|
35
+ @assemblies << line.strip
36
+ }
37
+
38
+ return if parts.length < 2
39
+
40
+ folders = parts[1].split(',')
41
+ folders.each { |f|
42
+ @files << File.join(Dir.pwd, "#{f}/*")
43
+ }
44
+
45
+ return if parts.length < 3
46
+
47
+ @depends = JSON.parse parts[2]
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,82 @@
1
+ class String
2
+
3
+ def colorize(text, color_code)
4
+ "\e[#{color_code}m#{text}\e[0m"
5
+ end
6
+ def black
7
+ colorize self, 30
8
+ end
9
+ def red
10
+ colorize self, 31
11
+ end
12
+ def green
13
+ colorize self, 32
14
+ end
15
+ def white
16
+ colorize self, 33
17
+ end
18
+ def blue
19
+ colorize self, 34
20
+ end
21
+ def magenta
22
+ colorize self, 35
23
+ end
24
+ def cyan
25
+ colorize self, 36
26
+ end
27
+ def yellow
28
+ colorize self, 37
29
+ end
30
+
31
+ def bg_black
32
+ colorize self, 40
33
+ end
34
+ def bg_red
35
+ colorize self, 41
36
+ end
37
+ def bg_green
38
+ colorize self, 42
39
+ end
40
+ def bg_white
41
+ colorize self, 43
42
+ end
43
+ def bg_blue
44
+ colorize self, 44
45
+ end
46
+ def bg_magenta
47
+ colorize self, 45
48
+ end
49
+ def bg_cyan
50
+ colorize self, 46
51
+ end
52
+ def bg_yellow
53
+ colorize self, 47
54
+ end
55
+
56
+ def bold
57
+ "\e[1m#{self}\e[22m"
58
+ end
59
+ def italic
60
+ "\e[3m#{self}\e[23m"
61
+ end
62
+ def underline
63
+ "\e[4m#{self}\e[24m"
64
+ end
65
+ def blink
66
+ "\e[5m#{self}\e[25m"
67
+ end
68
+ def reverse_color
69
+ "\e[7m#{self}\e[27m"
70
+ end
71
+
72
+ def expand_with list
73
+ out = []
74
+ list.each{ |i|
75
+ f = self + '.' + i
76
+ if File.exists? f
77
+ out << f
78
+ end
79
+ }
80
+ out
81
+ end
82
+ end
data/lib/versioning.rb ADDED
@@ -0,0 +1,135 @@
1
+ ASTER = '*'
2
+ CSPROJ = '.csproj'
3
+
4
+ $version_map = {}
5
+
6
+ def get_commit_hash_and_date
7
+ begin
8
+ commit = `git log -1 --pretty=format:%H`
9
+ git_date = `git log -1 --date=iso --pretty=format:%ad`
10
+ commit_date = DateTime.parse( git_date ).strftime("%Y-%m-%d %H%M%S")
11
+ rescue
12
+ commit = "git unavailable"
13
+ end
14
+
15
+ [commit, commit_date]
16
+ end
17
+
18
+ # put semver versions in a map
19
+ def read_versions
20
+
21
+ return $version_map if !$version_map.empty?
22
+
23
+ files = Dir['.semver/**/*.semver']
24
+ files.each { | file |
25
+ v = SemVer.new
26
+ v.load file
27
+ v.patch = (ENV['BUILD_NUMBER'] || v.patch).to_i
28
+ version = versions(v, &method(:commit_data))
29
+
30
+ sm = SemVerMetadata.new file
31
+ assemblies = sm.assemblies
32
+ sm.assemblies.each { |a|
33
+ $version_map[a] = version
34
+ }
35
+
36
+ name = file
37
+ .gsub(/.semver/, '')
38
+ .gsub('/', '')
39
+
40
+ $version_map[name] = version
41
+ }
42
+
43
+ # this is for assemblies not versioned with semver
44
+ $version_map[ASTER] = versions_no_semver(&method(:commit_data))
45
+
46
+ $version_map
47
+ end
48
+
49
+ def update_assembly_versions
50
+ require 'albacore/task_types/asmver'
51
+
52
+ $version_map = read_versions
53
+
54
+ files = FileList['**/*' + CSPROJ]
55
+ files.each { |f|
56
+
57
+ ns = File.basename(f, CSPROJ)
58
+
59
+ asm_file = File.join File.dirname(f), '/Properties/AssemblyVersion.cs'
60
+ next if ns.nil? || ns.to_s == '' || !File.file?(asm_file)
61
+
62
+ c = Albacore::Asmver::Config.new
63
+ c.file_path = asm_file
64
+
65
+ if ($version_map.key? ns)
66
+ c.attributes assembly_configuration: BUILD_CONFIG,
67
+ assembly_version: $version_map[ns][:long_version],
68
+ assembly_file_version: $version_map[ns][:long_version],
69
+ assembly_informational_version: $version_map[ns][:build_version]
70
+ else
71
+ c.attributes assembly_configuration: BUILD_CONFIG,
72
+ assembly_version: $version_map[ASTER][:long_version],
73
+ assembly_file_version: $version_map[ASTER][:long_version],
74
+ assembly_informational_version: $version_map[ASTER][:build_version]
75
+ end
76
+
77
+ Albacore::Asmver::Task.new(c.opts).execute
78
+ }
79
+ end
80
+
81
+ def self.versions semver, &commit_data
82
+ {
83
+ # just a monotonic inc
84
+ :build_number => semver.patch,
85
+ :semver => semver,
86
+
87
+ # purely M.m.p format
88
+ :formal_version => "#{ XSemVer::SemVer.new(semver.major, semver.minor, semver.patch).format "%M.%m.%p"}",
89
+
90
+ # four-numbers version, useful if you're dealing with COM/Windows
91
+ :long_version => "#{semver.format '%M.%m.%p'}.0",
92
+
93
+ # extensible number w/ git hash
94
+ :build_version => semver.format("%M.%m.%p%s") + ".#{yield[0]}",
95
+
96
+ # nuget (not full semver 2.0.0 support) see http://nuget.codeplex.com/workitem/1796
97
+ :nuget_version => format_nuget(semver)
98
+ }
99
+ end
100
+
101
+ def self.versions_no_semver &commit_data
102
+ dt_ver = Time.new.strftime('%y.%-m.%-d') + ".#{(ENV['BUILD_NUMBER'] || '0')}"
103
+ {
104
+
105
+ :formal_version => dt_ver,
106
+
107
+ # four-numbers version, useful if you're dealing with COM/Windows
108
+ :long_version => dt_ver,
109
+
110
+ # extensible number w/ git hash
111
+ :build_version => dt_ver + ".#{yield[0]}"
112
+ }
113
+ end
114
+
115
+ def self.format_nuget semver
116
+ if semver.prerelease and not semver.prerelease.empty?
117
+ "#{semver.major}.#{semver.minor}.#{semver.patch}-#{semver.prerelease.gsub(/\W/, '')}"
118
+ else
119
+ semver.format '%M.%m.%p'
120
+ end
121
+ end
122
+
123
+ # load the commit data
124
+ # returns: [short-commit :: String, date :: DateTime]
125
+ def self.commit_data
126
+ begin
127
+ commit = `git rev-parse --short HEAD`.chomp()[0,6]
128
+ git_date = `git log -1 --date=iso --pretty=format:%ad`
129
+ commit_date = DateTime.parse( git_date ).strftime("%Y-%m-%d %H:%M:%S")
130
+ rescue
131
+ commit = (ENV['BUILD_VCS_NUMBER'] || "000000")[0,6]
132
+ commit_date = Time.new.strftime("%Y-%m-%d %H:%M:%S")
133
+ end
134
+ [commit, commit_date]
135
+ end
data/rakefile.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: azbuild
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Suresh Batta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Build, Configuration and Deployment Gem for .Net Solutions
14
+ email: subatta@hotmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - azbuild.gemspec
21
+ - lib/azbuild.rb
22
+ - lib/build.rb
23
+ - lib/install.rb
24
+ - lib/package.rb
25
+ - lib/semver_extensions.rb
26
+ - lib/string_extensions.rb
27
+ - lib/versioning.rb
28
+ - rakefile.rb
29
+ homepage: http://rubygems.org/gems/azbuild
30
+ licenses:
31
+ - MIT
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.5.1
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Setup and scripting support for .Net project builds
53
+ test_files: []