bozo-scripts 0.1.5 → 0.1.6

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.
@@ -0,0 +1,34 @@
1
+ module Bozo::Preparers
2
+
3
+ class CommonAssemblyInfo
4
+
5
+ def company_name(name)
6
+ @company_name = name
7
+ end
8
+
9
+ def execute
10
+ log_info 'Generating common assembly info'
11
+
12
+ git_hash = env['GIT_HASH_FULL']
13
+ computer_name = env['COMPUTERNAME']
14
+ trademark = computer_name ? "#{computer_name} #{git_hash}" : git_hash
15
+ path = File.expand_path(File.join('build', 'CommonAssemblyInfo.cs'))
16
+
17
+ log_debug "Version: #{version}"
18
+ log_debug "Commit hash: #{git_hash}"
19
+ log_debug "Computer name: #{computer_name}" if computer_name
20
+ log_debug "Path: #{path}"
21
+
22
+ File.open(path, 'w+') do |f|
23
+ f << "using System.Reflection;\n"
24
+ f << "\n"
25
+ f << "[assembly: AssemblyCompany(\"#{@company_name}\")]\n"
26
+ f << "[assembly: AssemblyVersion(\"#{version}\")]\n"
27
+ f << "[assembly: AssemblyFileVersion(\"#{version}\")]\n"
28
+ f << "[assembly: AssemblyTrademark(\"#{trademark}\")]"
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,152 @@
1
+ module Bozo::Preparers
2
+
3
+ # Preparer for creating files based upon configuration files and ERB-style
4
+ # templates before any compilation occurs.
5
+ #
6
+ # == Overview
7
+ #
8
+ # This preparer is primarily intended for generating config files with shared
9
+ # values but it is capable of generating whatever files you want. Each
10
+ # instance of the preparer is isolated from the anothers so you could specify
11
+ # multiple preparers to work with different configurations and templates if
12
+ # you wished.
13
+ #
14
+ # By default the preparer will load <tt>default.rb</tt> followed by
15
+ # <tt>[environment].rb</tt> followed by <tt>[machine_name].rb</tt> from the
16
+ # configured config_path if the file exists. It will then load any files
17
+ # explicitly required through the config_file method.
18
+ #
19
+ # == Hook configuration
20
+ #
21
+ # prepare :file_templating do |t|
22
+ # t.config_path 'somewhere' # defaults to 'config' if not specified
23
+ # t.config_file 'my/specific/file.rb' # must be a specific file
24
+ # t.template_files 'src/**/*.config.template' # can use glob format
25
+ # end
26
+ #
27
+ # Source files are expected to have an additional extension compared to the
28
+ # target file. For example, a source file of
29
+ # <tt>src/csharp/Project/Project.config.template</tt> will generate the file
30
+ # <tt>src/csharp/Project/Project.config</tt>.
31
+ #
32
+ # == Configuration files
33
+ #
34
+ # Configuration files specify a hash of hashes in a more readable format.
35
+ # For example:
36
+ #
37
+ # group :example do
38
+ # set :one, 'foo'
39
+ # set :two, 'bar'
40
+ # end
41
+ #
42
+ # Internally creates a hash like:
43
+ #
44
+ # {:example => {:one => 'foo', :two => 'bar'}}
45
+ #
46
+ # A configuration file can overwrite the values specified by a preceding one
47
+ # without error. Groups can be opened and closed as desired and nesting
48
+ # groups is possible.
49
+ #
50
+ # == Template files
51
+ #
52
+ # To use a value within an ERB template you specify the hash hierarchy as if
53
+ # they were method names rather than having to use the full hash syntax.
54
+ #
55
+ # Therefore, this is valid:
56
+ #
57
+ # Foo is <%= example.one %>
58
+ #
59
+ # Whilst this is *not* valid:
60
+ #
61
+ # Foo is <%= self[:example][:one] %>
62
+ #
63
+ # If a template uses a value that is not specified within the configuration
64
+ # then the preparer will raise an error and halt the build.
65
+ class FileTemplating
66
+
67
+ # Creates a new instance.
68
+ def initialize
69
+ @config_path = 'config'
70
+ @template_globs = []
71
+ @config_files = []
72
+ end
73
+
74
+ # Sets the path of the directory within which the preparer should look for
75
+ # the default configuration files.
76
+ #
77
+ # @param [String] path
78
+ # The path to the directory containing the default configuration files.
79
+ def config_path(path)
80
+ @config_path = path
81
+ end
82
+
83
+ # Adds a specific file to load configuration from.
84
+ #
85
+ # @param [String] path
86
+ # The path to a configuration file.
87
+ def config_file(path)
88
+ @config_files << path
89
+ end
90
+
91
+ # Adds a set of templates files from which to generate files.
92
+ #
93
+ # @param [String] glob
94
+ # A glob that points to a set of files that should pass through the
95
+ # templating engine.
96
+ def template_files(glob)
97
+ @template_globs << glob
98
+ end
99
+
100
+ # Generate all the files matching the configuration.
101
+ def execute
102
+ log_info '' # formatting
103
+ log_info 'Generating files'
104
+
105
+ get_coordinator.generate_files do |template, target|
106
+ log_debug "Generating #{target} from #{template}"
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ # Creates a new templating coordinator based upon the current
113
+ # configuration.
114
+ def get_coordinator
115
+ coordinator = Bozo::ErubisTemplatingCoordinator.new
116
+
117
+ add_config coordinator
118
+ add_templates coordinator
119
+
120
+ coordinator
121
+ end
122
+
123
+ # Adds the configuration to the templating coordinator.
124
+ def add_config(coordinator)
125
+ add_default_config_files coordinator
126
+ @config_files.each {|f| coordinator.required_config_file f}
127
+ end
128
+
129
+ # Adds the default configuration from the configuration directory to the
130
+ # templating coordinator.
131
+ #
132
+ # @param [ErubisTemplatingCoordinator] coordinator
133
+ # The template coordinator to add the configuration to.
134
+ def add_default_config_files(coordinator)
135
+ default_files = ['default.rb', "#{environment}.rb"]
136
+ default_files << "#{env['MACHINENAME']}.rb" if env['MACHINENAME']
137
+
138
+ default_files.each do |file|
139
+ coordinator.config_file File.join(@config_path, file)
140
+ end
141
+ end
142
+
143
+ # Adds the templates to the templating coordinator.
144
+ def add_templates(coordinator)
145
+ @template_globs.each do |glob|
146
+ coordinator.template_files glob
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+ end
@@ -0,0 +1,83 @@
1
+ require 'fileutils'
2
+
3
+ module Bozo::Publishers
4
+
5
+ # Publisher that copies files from one location to another.
6
+ class FileCopy
7
+
8
+ # Creates a new instance.
9
+ def initialize
10
+ @directories = []
11
+ end
12
+
13
+ # Adds a source directory of files copy.
14
+ #
15
+ # Must be relative to the project root. All files within the directory and
16
+ # its subdirectories will be copied to the destination directory,
17
+ # maintaining the file structure.
18
+ #
19
+ # @params [Array] args
20
+ # Path to a directory relative to the project root.
21
+ def directory(*args)
22
+ @directories << args
23
+ end
24
+
25
+ # Set the destination directory of the file copy.
26
+ #
27
+ # Must be an absolute path.
28
+ #
29
+ # @params [String] destination
30
+ # The absolution path the source files should be copied to.
31
+ def destination(destination)
32
+ @destination = destination
33
+ end
34
+
35
+ def execute
36
+ if @directories.empty? or @destination.nil?
37
+ raise Bozo::ConfigurationError.new 'You must specify at least one source file or directory AND a destination directory'
38
+ end
39
+
40
+ ensure_no_clashing_files
41
+
42
+ copy_pairs do |source, target|
43
+ FileUtils.mkdir_p File.dirname(target)
44
+ log_debug "Publishing \"#{File.basename(source)}\" to \"#{target}\""
45
+ FileUtils.cp source, target
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # Checks the destination does not contain files that will be overwritten by
52
+ # the source files.
53
+ def ensure_no_clashing_files
54
+ existing_files = []
55
+
56
+ copy_pairs do |source, target|
57
+ existing_files << target if File.exist? target
58
+ end
59
+
60
+ raise Bozo::ConfigurationError.new "Target files already exist - #{existing_files}" unless existing_files.empty?
61
+ end
62
+
63
+ # Returns the source-destination file pairs specified by the source
64
+ # directories and destination directory.
65
+ def copy_pairs # :yields: source_path, destination_path
66
+ destination = File.join @destination
67
+
68
+ @directories.each do |dir|
69
+ relative_source_dir = File.join(dir)
70
+ source_dir = File.expand_path relative_source_dir
71
+ source_dir_path = Pathname.new source_dir
72
+
73
+ Dir[File.join(source_dir, '**', '*')].each do |source_file|
74
+ rel_path = Pathname.new(source_file).relative_path_from(source_dir_path).to_s
75
+ target_file = File.join(destination, rel_path)
76
+ yield source_file, target_file
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,18 @@
1
+ module Bozo::Publishers
2
+
3
+ # Publisher that publishes gem files to rubygems.org
4
+ class Rubygems
5
+
6
+ def execute
7
+ Dir['dist/gem/*.gem'].each { |gem| push gem }
8
+ end
9
+
10
+ private
11
+
12
+ def push(gem)
13
+ execute_command :rubygems, ['gem', 'push', gem]
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,158 @@
1
+ require 'nokogiri'
2
+
3
+ module Bozo::TestRunners
4
+
5
+ # Adds a code coverage test runner using dotCover
6
+ #
7
+ # The default configuration looks for dotCover in the ProgramFiles(x86) path
8
+ #
9
+ # Test runners can be defined for dotCover to run against. Each runner
10
+ # produces a separate dotcover output
11
+ class DotCover
12
+ def self.default_path
13
+ if ENV['teamcity.dotCover.home'].nil?
14
+ if ENV['ProgramFiles(x86)'].nil?
15
+ program_files_path = ENV['ProgramFiles']
16
+ else
17
+ program_files_path = ENV['ProgramFiles(x86)']
18
+ end
19
+
20
+ File.join(program_files_path, 'JetBrains', 'dotCover', 'v1.2', 'Bin', 'dotcover.exe')
21
+ else
22
+ File.join(ENV['teamcity.dotCover.home'], 'dotcover.exe')
23
+ end
24
+ end
25
+
26
+ def initialize
27
+ @@defaults = {
28
+ :path => DotCover.default_path,
29
+ :required => true
30
+ }
31
+
32
+ @config = {}
33
+ @runners = []
34
+ end
35
+
36
+ # Returns whether dotcover is installed at the configured path
37
+ def dotcover_installed?
38
+ path = configuration[:path]
39
+
40
+ return false if path.nil?
41
+
42
+ File.exist? path
43
+ end
44
+
45
+ # Adds a test runner
46
+ #
47
+ # @param [Symbol] runner
48
+ # A test runner to wrap with dotcover
49
+ def runner(runner, &block)
50
+ add_instance runner, block
51
+ end
52
+
53
+ # Specifies whether covering with dotcover is required
54
+ #
55
+ # If it is not required, and dotcover cannot be found, then test runners
56
+ # are executed without coverage. If dotcover is required but cannot be
57
+ # found then an error will occur.
58
+ #
59
+ # @param [boolean] required
60
+ # Whether dotCover coverage is required
61
+ def required?(required = nil)
62
+ @config[:required] = required unless required.nil?
63
+
64
+ @config[:required]
65
+ end
66
+
67
+ def execute
68
+ if required? or dotcover_installed?
69
+ @runners.each {|runner| execute_with_coverage runner}
70
+ else
71
+ @runners.each {|runner| execute_without_coverage(runner)}
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # Resolves the named class within the given namespace and then created an
78
+ # instance of the class before adding it to the given collection and
79
+ # yielding it to the configuration block when one is provided.
80
+ #
81
+ # @param [Symbol] type
82
+ # The name of the step executor.
83
+ # @param [Proc] block
84
+ # Optional block to refine the configuration of the step executor.
85
+ def add_instance(type, block)
86
+ instance = Bozo::TestRunners.const_get(to_class_name(type)).new
87
+ instance.extend Bozo::Runner
88
+ @runners << instance
89
+ block.call instance if block
90
+ end
91
+
92
+ # Converts a symbol into a Pascal Case class name.
93
+ #
94
+ # eg. `:single` => `"Single"`, `:two_words` => `"TwoWords"`.
95
+ #
96
+ # @param [Symbol] type
97
+ # The name of a step executor.
98
+ def to_class_name(type)
99
+ type.to_s.split('_').map{|word| word.capitalize}.join
100
+ end
101
+
102
+ def execute_without_coverage(runner)
103
+ log_debug 'Running ' + runner.class.to_s + ' without coverage'
104
+ runner.execute
105
+ end
106
+
107
+ def execute_with_coverage(runner)
108
+ if required? & !dotcover_installed?
109
+ log_fatal "Attempting to run with coverage but dotcover could not be found at #{configuration[:path]}"
110
+ end
111
+
112
+ log_debug "Running #{runner.class} with coverage"
113
+
114
+ config = configuration
115
+ dotcover_path = config[:path]
116
+ coverage_path = generate_coverage_file runner
117
+
118
+ args = []
119
+ args << '"' + dotcover_path + '"'
120
+ args << "analyse #{coverage_path}"
121
+
122
+ log_debug 'Running dotcover from "' + dotcover_path + '"'
123
+ execute_command :dot_cover, args
124
+ end
125
+
126
+ def generate_coverage_file(runner)
127
+ output_file = File.expand_path(File.join('temp', 'dotcover', "#{Time.now.to_i}-dotcover-report.xml"))
128
+
129
+ runner_args = runner.runner_args
130
+ runner_args.flatten!
131
+
132
+ builder = Nokogiri::XML::Builder.new do |doc|
133
+ doc.AnalyseParams do
134
+ doc.Executable runner.runner_path.gsub(/\//, '\\')
135
+ doc.Arguments runner_args.join(' ')
136
+ doc.WorkingDir File.expand_path(File.join('temp', 'dotcover'))
137
+ doc.Output output_file
138
+ end
139
+ end
140
+
141
+ coverage_path = File.expand_path(File.join('temp', 'dotcover', "coverage.xml"))
142
+ FileUtils.mkdir_p File.dirname(coverage_path)
143
+ File.open(coverage_path, 'w+') {|f| f.write(builder.to_xml)}
144
+
145
+ coverage_path
146
+ end
147
+
148
+ def configuration
149
+ config_with_defaults
150
+ end
151
+
152
+ def config_with_defaults
153
+ @@defaults.merge @config
154
+ end
155
+
156
+ end
157
+
158
+ end
@@ -0,0 +1,131 @@
1
+ module Bozo::TestRunners
2
+
3
+ # A TestRunner for NUnit
4
+ # By default the x64 runner is used. If you want to use a different
5
+ # platform runner then set the platform, e.g. 'x86'.
6
+ #
7
+ # == Dotcover integration
8
+ # To enable integration with the dotcover test runner the following
9
+ # interface needs to be used
10
+ #
11
+ # runner_path # should return the path to the runners executable
12
+ # runner_args # should return the arguments to be passed to use
13
+ class Nunit
14
+
15
+ def initialize
16
+ @projects = []
17
+ @include = []
18
+ @exclude = []
19
+ end
20
+
21
+ def destination(destination)
22
+ @destination = destination
23
+ end
24
+
25
+ def platform(platform)
26
+ @platform = platform
27
+ end
28
+
29
+ def project(path)
30
+ @projects << path
31
+ end
32
+
33
+ def report_path(path)
34
+ @report_path = path
35
+ end
36
+
37
+ def coverage(coverage)
38
+ @coverage = coverage
39
+ end
40
+
41
+ def include(include)
42
+ cannot_define_both_include_and_exclude_categories if @exclude.any?
43
+ @include << include
44
+ end
45
+
46
+ def exclude(exclude)
47
+ cannot_define_both_include_and_exclude_categories if @include.any?
48
+ @exclude << exclude
49
+ end
50
+
51
+ def to_s
52
+ "Run tests with nunit against projects #{@projects}"
53
+ end
54
+
55
+ # Returns the path to the runner's executable.
56
+ #
57
+ # @returns [String]
58
+ def runner_path
59
+ exe_name = "nunit-console.exe"
60
+
61
+ if defined? @platform
62
+ log_debug "Looking for runner with #@platform platform"
63
+ exe_name = "nunit-console-#@platform.exe"
64
+ end
65
+
66
+ nunit_runners = expand_and_glob('packages', 'NUnit*', 'tools', exe_name)
67
+ raise nunit_runner_not_found if nunit_runners.empty?
68
+ raise multiple_runners_found if nunit_runners.size > 1
69
+
70
+ nunit_runner = nunit_runners.first
71
+
72
+ log_debug "Found runner at #{nunit_runner}"
73
+
74
+ nunit_runner
75
+ end
76
+
77
+ # Returns the arguments required for the runner's executable.
78
+ #
79
+ # @returns [Array]
80
+ def runner_args
81
+ args = []
82
+
83
+ @projects.each do |project|
84
+ expand_and_glob('temp', 'msbuild', project, '**', "#{project}.dll").each do |test_dll|
85
+ args << "\"#{test_dll}\""
86
+ end
87
+ end
88
+ args << '/nologo'
89
+
90
+ report_path = @report_path
91
+ report_path = expand_path('temp', 'nunit', "#{Time.now.to_i}-nunit-report.xml") unless report_path
92
+
93
+ # Ensure the directory is there because NUnit won't make it
94
+ FileUtils.mkdir_p File.dirname(report_path)
95
+
96
+ args << "/xml:\"#{report_path}\""
97
+ args << "/include:#{@include.join(',')}" if @include.any?
98
+ args << "/exclude:#{@exclude.join(',')}" if @exclude.any?
99
+
100
+ args
101
+ end
102
+
103
+ def execute
104
+ execute_command :nunit, [runner_path] << runner_args
105
+ end
106
+
107
+ private
108
+
109
+ def nunit_runner_not_found
110
+ Bozo::ConfigurationError.new 'No NUnit runners found. You must install one via nuget.'
111
+ end
112
+
113
+ def multiple_runners_found
114
+ Bozo::ConfigurationError.new 'Multiple NUnit runners found. There should only be one.'
115
+ end
116
+
117
+ def expand_path(*args)
118
+ File.expand_path(File.join(args))
119
+ end
120
+
121
+ def expand_and_glob(*args)
122
+ Dir[expand_path(*args)]
123
+ end
124
+
125
+ def cannot_define_both_include_and_exclude_categories
126
+ raise Bozo::ConfigurationError.new 'Both include and exclude categories defined. You cannot specify both for nunit.'
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,35 @@
1
+ module Bozo::TestRunners
2
+
3
+ class Runit
4
+
5
+ def initialize
6
+ @paths = []
7
+ end
8
+
9
+ def path(path)
10
+ @paths << path
11
+ end
12
+
13
+ def execute
14
+ require 'test/unit'
15
+
16
+ test_files = []
17
+
18
+ @paths.each do |p|
19
+ Dir[p].select {|f| (File.extname f) == '.rb'}.each {|f| test_files << f}
20
+ end
21
+
22
+ # raise an error if no test files were found. This may indicate a configuration issue
23
+ raise Bozo::ConfigurationError.new "No tests found" unless test_files.any?
24
+ raise Bozo::ExecutionError.new(:runit, test_files, -1) unless execute_tests test_files
25
+ end
26
+
27
+ private
28
+
29
+ def execute_tests(test_files)
30
+ Test::Unit::AutoRunner.run(true, nil, test_files)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,5 @@
1
+ module BozoScripts
2
+
3
+ VERSION = File.read(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../../VERSION')).strip
4
+
5
+ end
@@ -0,0 +1,26 @@
1
+ $:.push File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'fileutils'
4
+ require 'rainbow'
5
+ require 'bozo'
6
+
7
+ require 'bozo/compilers/msbuild'
8
+ require 'bozo/dependency_resolvers/bundler'
9
+ require 'bozo/dependency_resolvers/nuget'
10
+ require 'bozo/hooks/fxcop'
11
+ require 'bozo/hooks/git_commit_hashes'
12
+ require 'bozo/hooks/git_tag_release'
13
+ require 'bozo/hooks/teamcity'
14
+ require 'bozo/hooks/timing'
15
+ require 'bozo/packagers/rubygems'
16
+ require 'bozo/packagers/nuget'
17
+ require 'bozo/preparers/common_assembly_info'
18
+ require 'bozo/preparers/file_templating'
19
+ require 'bozo/publishers/file_copy'
20
+ require 'bozo/publishers/rubygems'
21
+ require 'bozo/test_runners/dotcover'
22
+ require 'bozo/test_runners/nunit'
23
+ require 'bozo/test_runners/runit'
24
+ require 'bozo/configuration'
25
+ require 'bozo/erubis_templating_coordinator'
26
+ require 'bozo/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bozo-scripts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garry Shutler
@@ -88,7 +88,30 @@ email:
88
88
  executables: []
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
- files: []
91
+ files:
92
+ - lib/bozo/compilers/msbuild.rb
93
+ - lib/bozo/configuration.rb
94
+ - lib/bozo/dependency_resolvers/bundler.rb
95
+ - lib/bozo/dependency_resolvers/nuget.rb
96
+ - lib/bozo/erubis_templating_coordinator.rb
97
+ - lib/bozo/hooks/fxcop.rb
98
+ - lib/bozo/hooks/git_commit_hashes.rb
99
+ - lib/bozo/hooks/git_tag_release.rb
100
+ - lib/bozo/hooks/teamcity.rb
101
+ - lib/bozo/hooks/timing.rb
102
+ - lib/bozo/packagers/nuget.rb
103
+ - lib/bozo/packagers/rubygems.rb
104
+ - lib/bozo/preparers/common_assembly_info.rb
105
+ - lib/bozo/preparers/file_templating.rb
106
+ - lib/bozo/publishers/file_copy.rb
107
+ - lib/bozo/publishers/rubygems.rb
108
+ - lib/bozo/test_runners/dotcover.rb
109
+ - lib/bozo/test_runners/nunit.rb
110
+ - lib/bozo/test_runners/runit.rb
111
+ - lib/bozo/version.rb
112
+ - lib/bozo_scripts.rb
113
+ - VERSION
114
+ - LICENSE
92
115
  homepage: https://github.com/zopaUK/bozo-scripts
93
116
  licenses: []
94
117
  metadata: {}