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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Mzc4OTE0Y2I1MTVmMWY2YjAzZjNhYzQ3YzllN2E0NDYzMzk1OWJhYg==
4
+ Y2EzNTg1MWEzZTViZjVkMWU2MGU2M2EyYWYwOTc1ZmRhNjhlZTBmYw==
5
5
  data.tar.gz: !binary |-
6
- NGQwYjRjYWZkM2I2YzEzOWQ2ZDAzZDIyOWQ3ODI4YTJhMGNiZjM0Yg==
6
+ ZmExNzBmOWFhNzFkZTEzNWVhYWFhMTA4NmY4YTM1NTI5YjFjMjg1Nw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- Mjc3NjZmNzA4NWE3NzcyMjg2YmYwOGEzYTY2ZWVmMzM0YTEzNjBjMzc0Y2Vk
10
- N2FmYjc1ZjQ4ZjA3ZWQ2NmM2ZjQ5ZDA5ZTRmNGYxNmIxYzkxNzYyOGI3YWM5
11
- YzNhNTQzMDI3MzY1MGRhMmQyMWZhZGMwMDNlNmFhMWJkYjFkOTM=
9
+ MWY0OTkyOWViMmM1ZWQ1ZTRlZDU0OWI1MWI2ZTM2Zjc3YzRiMjc2NWQ5NTJi
10
+ OTJmYTVjMWI5MzVhZjFiZmE1MTcxNWUyZGRkMjZkYjMyYjg5ZWJlYjFlODA0
11
+ ZTAxMWYyMjU2MjI1Njg1YjM5Y2M3NWE2ZDBjNjg5ZDU3OGM4YTM=
12
12
  data.tar.gz: !binary |-
13
- MzkxYjI1YjRiNTYzYzlmYWY5NWM3OGRlZGM0NTY3Y2QxOTc2M2E0YzY2ODc1
14
- MDdlMDVmZWU3ZTgzOThhYjUwMzc0NWY2NTM2NjQyMDRhZDJhMDg1YzViYjM2
15
- MDgyNTQ3OWMzN2QxZWU2NTA3MTk1NWY2YmM1MDk0NDY4YmUxOGM=
13
+ YmVkZjA1OWFhZDUwZTNkYTAxMjEyMDA5YjkyYjZhN2Y2ZWJkZjMxNDM3OTU3
14
+ ZmRmMGM2ZTU0YjRkNTdkMDZlYjI0ZmM0ZWI2YmViMzQ1NDMyZDM1MTZlMWZl
15
+ YjRiN2U5MzM2OWQ5ZGVjN2UyMzg2NWEzOWVhMjkwOWZkZjU4YjM=
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2012 Zopa Ltd
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.6
@@ -0,0 +1,279 @@
1
+ require 'nokogiri'
2
+
3
+ module Bozo::Compilers
4
+
5
+ class Msbuild
6
+
7
+ def config_with_defaults
8
+ defaults = {
9
+ :version => 'v4.0.30319',
10
+ :framework => 'Framework64',
11
+ :properties => {:configuration => :release},
12
+ :max_cores => nil
13
+ }
14
+
15
+ default_targets = [:build]
16
+
17
+ config = defaults.merge @config
18
+ config[:targets] = (@targets or default_targets).clone
19
+ config[:websites_as_zip] = false
20
+ config
21
+ end
22
+
23
+ def initialize
24
+ @config = {}
25
+ @exclude_projects = []
26
+ end
27
+
28
+ def version(version)
29
+ @config[:version] = version
30
+ end
31
+
32
+ def framework(framework)
33
+ @config[:framework] = framework
34
+ end
35
+
36
+ def solution(path)
37
+ @config[:solution] = path
38
+ end
39
+
40
+ def property(args)
41
+ @config[:properties] ||= {}
42
+ @config[:properties] = @config[:properties].merge(args)
43
+ end
44
+
45
+ def exclude_project(project_name)
46
+ @exclude_projects << project_name
47
+ end
48
+
49
+ def websites_as_zip?
50
+ @config[:websites_as_zip] = true
51
+ end
52
+
53
+ # Assign how many cores should be used by msbuild
54
+ #
55
+ # @param [Integer] cores
56
+ # The maximum number of cores to allow msbuild to use
57
+ def max_cores(cores)
58
+ @config[:max_cores] = cores
59
+ end
60
+
61
+ alias :properties :property
62
+
63
+ def target(target)
64
+ @targets ||= []
65
+ @targets << target
66
+ end
67
+
68
+ def to_s
69
+ config = configuration
70
+ "Compile with msbuild #{config[:version]} building #{config[:solution]} with properties #{config[:properties]} for targets #{config[:targets]}"
71
+ end
72
+
73
+ def without_stylecop
74
+ @config[:without_stylecop] = true
75
+ end
76
+
77
+ def configuration
78
+ config_with_defaults
79
+ end
80
+
81
+ def execute
82
+ projects = (project_files('test') | project_files('src')).map { |file| create_project file }
83
+
84
+ # Clean all the projects first.
85
+ projects.each do |project|
86
+ project.clean configuration
87
+ end
88
+
89
+ # Build all the projects so they can utilize each others artifacts.
90
+ projects.each do |project|
91
+ project.build configuration
92
+ end
93
+ end
94
+
95
+ def project_files(directory)
96
+ project_file_matcher = File.expand_path(File.join(directory, 'csharp', '**', '*.csproj'))
97
+ Dir[project_file_matcher].select { |p| not @exclude_projects.include?(File.basename p, '.csproj') }
98
+ end
99
+
100
+ def required_tools
101
+ :stylecop unless @config[:without_stylecop]
102
+ end
103
+
104
+ private
105
+
106
+ # Creates a project based on the project_file type.
107
+ # Defaults to a class library project if it cannot be determined.
108
+ # @return [Project]
109
+ def create_project(project_file)
110
+ project_name = File.basename(project_file).gsub(/\.csproj$/, '')
111
+ log_debug project_name
112
+
113
+ project_class_for(project_file).new project_file, project_name
114
+ end
115
+
116
+ # @return [Class]
117
+ def project_class_for(project_file)
118
+ project_types = project_types_from project_file
119
+ web_app_type = '{349c5851-65df-11da-9384-00065b846f21}'
120
+ if tools_version(project_file) == "3.5"
121
+ project_types.include?(web_app_type) ? WebProject2008 : ClassLibrary
122
+ else
123
+ project_types.include?(web_app_type) ? WebProject2010 : ClassLibrary
124
+ end
125
+ end
126
+
127
+ # @return [Array]
128
+ def project_types_from(project_file)
129
+ project_types = []
130
+
131
+ File.open(project_file) do |f|
132
+ element = Nokogiri::XML(f).css('Project PropertyGroup ProjectTypeGuids').first
133
+ project_types = element.content.split(';').map {|e| e.downcase } unless element.nil?
134
+ end
135
+
136
+ project_types
137
+ end
138
+
139
+ def tools_version(project_file)
140
+ tools_version = nil
141
+
142
+ File.open(project_file) do |f|
143
+ element = Nokogiri::XML(f).css('Project').first
144
+ tools_version = element['ToolsVersion'] unless element.nil?
145
+ end
146
+
147
+ tools_version
148
+ end
149
+
150
+ end
151
+
152
+ private
153
+
154
+ class Project
155
+
156
+ include Bozo::Runner
157
+
158
+ def initialize(project_file, project_name)
159
+ @project_file = project_file
160
+ @project_name = project_name
161
+ end
162
+
163
+ def build(configuration)
164
+ populate_config(configuration)
165
+ args = generate_args configuration
166
+ execute_command :msbuild, args
167
+ end
168
+
169
+ def clean(configuration)
170
+ configuration[:targets] = [:clean]
171
+ args = generate_args configuration
172
+ execute_command :msbuild, args
173
+ end
174
+
175
+ def framework_version
176
+ framework_version = 'unknown'
177
+
178
+ File.open(@project_file) do |f|
179
+ framework_version = Nokogiri::XML(f).css('Project PropertyGroup TargetFrameworkVersion').first.content
180
+ framework_version = framework_version.sub('v', 'net').sub('.', '')
181
+ end
182
+
183
+ framework_version
184
+ end
185
+
186
+ def generate_args(config)
187
+ args = []
188
+
189
+ args << File.join(ENV['WINDIR'], 'Microsoft.NET', config[:framework], config[:version], 'msbuild.exe')
190
+ args << '/nologo'
191
+ args << '/verbosity:normal'
192
+ args << '/nodeReuse:false'
193
+ args << "/target:#{config[:targets].map{|t| t.to_s}.join(';')}"
194
+ args << "/maxcpucount" if config[:max_cores].nil? # let msbuild decide how many cores to use
195
+ args << "/maxcpucount:#{config[:max_cores]}" unless config[:max_cores].nil? # specifying the number of cores
196
+
197
+ config[:properties].each do |key, value|
198
+ args << "/property:#{key}=\"#{value}\""
199
+ end
200
+
201
+ args << "\"#{@project_file}\""
202
+ end
203
+
204
+ def windowsize_path(path)
205
+ path.gsub(/\//, '\\')
206
+ end
207
+
208
+ def location
209
+ File.expand_path(File.join('temp', 'msbuild', @project_name, framework_version))
210
+ end
211
+
212
+ end
213
+
214
+ class ClassLibrary < Project
215
+
216
+ def populate_config(config)
217
+ config[:properties][:outputpath] = location + '/'
218
+ config[:properties][:solutiondir] = windowsize_path(File.expand_path('.') + '//')
219
+ end
220
+
221
+ end
222
+
223
+ class WebProject2010 < Project
224
+
225
+ def populate_config(config)
226
+ config[:targets] << :package
227
+
228
+ config[:properties][:packagelocation] = location + '/Site.zip'
229
+ config[:properties][:packageassinglefile] = true
230
+
231
+ config[:properties][:solutiondir] = windowsize_path(File.expand_path('.') + '//')
232
+ end
233
+
234
+ end
235
+
236
+ class WebProject2008 < Project
237
+
238
+ require 'zip/zip'
239
+
240
+ def build(configuration)
241
+ super
242
+
243
+ zip_website if configuration[:websites_as_zip]
244
+ end
245
+
246
+ def zip_website
247
+ zip_file = zip_location_dir 'Site.zip'
248
+
249
+ Dir["#{location}/**/**"].reject { |f| f == zip_file }.each do |file|
250
+ FileUtils.rm_rf file
251
+ end
252
+ end
253
+
254
+ def zip_location_dir(zip_file_name)
255
+ zip_path = location + "/#{zip_file_name}"
256
+
257
+ Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE) do |zipfile|
258
+ Dir["#{location}/**/**"].each do |file|
259
+ zipfile.add(file.sub(location + '/', ''), file)
260
+ end
261
+ end
262
+
263
+ zip_path
264
+ end
265
+
266
+ def populate_config(config)
267
+ config[:targets] << :'ResolveReferences'
268
+ config[:targets] << :'_CopyWebApplication'
269
+
270
+ config[:properties][:OutDir] = location + '/bin/'
271
+ config[:properties][:WebProjectOutputDir] = windowsize_path location
272
+ config[:properties][:_DebugSymbolsProduced] = false
273
+
274
+ config[:properties][:solutiondir] = windowsize_path(File.expand_path('.') + '//')
275
+ end
276
+
277
+ end
278
+
279
+ end
@@ -0,0 +1,155 @@
1
+ module Bozo
2
+
3
+ # Class for generating configuration objects.
4
+ class Configuration
5
+
6
+ # Create a new instance.
7
+ def initialize
8
+ @root = ConfigurationGroup.new
9
+ @group_stack = [@root]
10
+ end
11
+
12
+ # Begin the definition of a group with the given name.
13
+ #
14
+ # @param [Symbol] name
15
+ # The name of the group.
16
+ def group(name)
17
+ new_group = @group_stack.last.ensure_child name
18
+ @group_stack.push new_group
19
+ yield
20
+ @group_stack.pop
21
+ end
22
+
23
+ # Set the value of the given key within the active group.
24
+ #
25
+ # @param [Symbol] key
26
+ # The key to set the value of within the active group.
27
+ # @param [Object] value
28
+ # The value to set the key to within the active group.
29
+ def set(key, value)
30
+ @group_stack.last.set_value(key, value)
31
+ end
32
+
33
+ # Returns the configuration value for the key
34
+ #
35
+ # @param [Symbol] key
36
+ def [](key)
37
+ @root[key]
38
+ end
39
+
40
+ # Load the specified file as an additional configuration file.
41
+ #
42
+ # == Usage
43
+ #
44
+ # Configuration files specify a hash of hashes in a more readable format.
45
+ # For example:
46
+ #
47
+ # group :example do
48
+ # set :one, 'foo'
49
+ # set :two, 'bar'
50
+ # end
51
+ #
52
+ # Internally creates a hash like:
53
+ #
54
+ # {:example => {:one => 'foo', :two => 'bar'}}
55
+ #
56
+ # A configuration file can overwrite the values specified by a preceding one
57
+ # without error. Groups can be opened and closed as desired and nesting
58
+ # groups is possible.
59
+ #
60
+ # @param [String] path
61
+ # The path of the configuration file.
62
+ def load(path)
63
+ instance_eval IO.read(path), path
64
+ end
65
+
66
+ # Yields the internal binding of the configuration to the given block.
67
+ #
68
+ # @param [Proc] block
69
+ # The block to yield the configuration's internal binding to.
70
+ def apply(&block)
71
+ @root.apply(block)
72
+ end
73
+
74
+ # Return the current state of the configuration.
75
+ def inspect
76
+ @root.inspect
77
+ end
78
+
79
+ private
80
+
81
+ # Class for controlling the creation and retrieval of configuration
82
+ # groups and values.
83
+ #
84
+ # Should not be used outside of this class.
85
+ class ConfigurationGroup # :nodoc:
86
+
87
+ # Create a new instance.
88
+ def initialize(*parents)
89
+ @parents = parents
90
+ @hash = {}
91
+ end
92
+
93
+ # Enables the fluent retrieval of groups within the hash.
94
+ def method_missing(sym, *args, &block)
95
+ raise missing_child sym unless @hash.key? sym
96
+ @hash[sym]
97
+ end
98
+
99
+ # Returns the configuration value for the key
100
+ #
101
+ # @param [Symbol] key
102
+ def [](key)
103
+ @hash[key]
104
+ end
105
+
106
+ # Ensures the hash contains a child hash for the specified key and
107
+ # returns it.
108
+ #
109
+ # @param [Symbol] key
110
+ # The key that must contain a child hash.
111
+ def ensure_child(key)
112
+ @hash[key] = ConfigurationGroup.new(@parents + [key]) unless @hash.key? key
113
+ @hash[key]
114
+ end
115
+
116
+ # Sets the value of the specified key.
117
+ #
118
+ # @param [Symbol] key
119
+ # The key to set the value of.
120
+ # @param [Object] value
121
+ # The value to set for the specified key.
122
+ def set_value(key, value)
123
+ @hash[key] = value
124
+ end
125
+
126
+ # Yields the internal binding of the configuration group to the given
127
+ # block.
128
+ #
129
+ # @param [Proc] block
130
+ # The block to yield the internal binding to.
131
+ def apply(block)
132
+ block.call(binding)
133
+ end
134
+
135
+ # Return the current state of the configuration.
136
+ def inspect
137
+ @hash.inspect
138
+ end
139
+
140
+ private
141
+
142
+ # Create a new error specifying that an attempt was made to retrieve a
143
+ # child that does not exist.
144
+ #
145
+ # @param [Symbol] sym
146
+ # The key of the requested child.
147
+ def missing_child(sym)
148
+ Bozo::ConfigurationError.new "#{@parents.any? ? @parents.join('.') : 'Root'} does not contain a value or group called '#{sym}' - known keys: #{@hash.keys.join(', ')}"
149
+ end
150
+
151
+ end
152
+
153
+ end
154
+
155
+ end
@@ -0,0 +1,54 @@
1
+ module Bozo::DependencyResolvers
2
+
3
+ # Class for resolving dependencies using Bundler.
4
+ class Bundler
5
+
6
+ # Creates a new instance.
7
+ def initialize
8
+ @pre = false
9
+ end
10
+
11
+ # Ensures Bundler is installed and then calls installs the gems specified
12
+ # in your Gemfile.
13
+ def execute
14
+ ensure_bundler_installed
15
+ install_gems
16
+ end
17
+
18
+ # Decides whether when installing Bundler if the pre version of the gem
19
+ # should be installed.
20
+ #
21
+ # @param [Boolean] pre
22
+ # Whether the pre version of the Bundler gem should be installed.
23
+ #
24
+ # The pre version of Bundler will not be used unless explicitly
25
+ # requested.
26
+ #
27
+ # Calling the method without any arguments will request that the pre
28
+ # version should be used.
29
+ def use_pre(pre = true)
30
+ @pre = pre
31
+ end
32
+
33
+ private
34
+
35
+ # Interrogates the list of installed gems and installs Bundler if it is
36
+ # not found.
37
+ def ensure_bundler_installed
38
+ return if `gem list bundler`.include? 'bundler'
39
+
40
+ args = %w{gem install --no-rdoc --no-ri bundler}
41
+ args << '--pre' if @pre
42
+
43
+ execute_command :rubygems, args
44
+ end
45
+
46
+ # Executes Bundler's install command, placing all of the installed gems
47
+ # into the <tt>build/bundler</tt> directory.
48
+ def install_gems
49
+ execute_command :bundler, %w{bundle install --path build/bundler}
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,86 @@
1
+ module Bozo::DependencyResolvers
2
+
3
+ # Class for resolving project dependencies using NuGet.
4
+ class Nuget
5
+
6
+ # Creates a new instance.
7
+ def initialize
8
+ @sources = []
9
+ end
10
+
11
+ # Add a URL that should be within the machine's configuration for
12
+ # package resolution URLs.
13
+ #
14
+ # @param [String] url
15
+ # A NuGet package resolving URL.
16
+ def source(url)
17
+ @sources << url
18
+ end
19
+
20
+ # Returns the build tools required for this dependency resolver to run
21
+ # successfully.
22
+ def required_tools
23
+ :nuget
24
+ end
25
+
26
+ # Ensure all the specified sources are present and execute the dependency
27
+ # resolver for all the files matching <tt>test/**/packages.config</tt> and
28
+ # <tt>src/**/packages.config</tt> and <tt>packages.config</tt> if present.
29
+ def execute
30
+ add_package_sources
31
+ install_packages 'test', '**', 'packages.config'
32
+ install_packages 'src', '**', 'packages.config'
33
+ install_packages 'packages.config'
34
+ end
35
+
36
+ private
37
+
38
+ # Adds any sources that are required but are not mentioned by the
39
+ # <tt>NuGet sources List</tt> command.
40
+ def add_package_sources
41
+ existing = `#{nuget_path} sources List` if @sources.any?
42
+
43
+ @sources.select {|source| not existing.upcase.include? source.upcase}.each do |source|
44
+ quoted_source = "\"#{source}\""
45
+ log_debug "Missing nuget package source #{quoted_source}"
46
+
47
+ args = []
48
+
49
+ args << nuget_path
50
+ args << 'sources'
51
+ args << 'Add'
52
+ args << '-Name'
53
+ args << quoted_source
54
+ args << '-Source'
55
+ args << quoted_source
56
+
57
+ log_debug "Adding nuget package source #{quoted_source}"
58
+
59
+ execute_command :nuget, args
60
+ end
61
+ end
62
+
63
+ def install_packages(*args)
64
+ path_matcher = File.expand_path(File.join(args))
65
+ Dir[path_matcher].each do |path|
66
+ args = []
67
+
68
+ args << nuget_path
69
+ args << 'install'
70
+ args << "\"#{path}\""
71
+ args << '-OutputDirectory'
72
+ args << "\"#{File.expand_path(File.join('packages'))}\""
73
+
74
+ log_debug "Resolving nuget dependencies for #{path}"
75
+
76
+ execute_command :nuget, args
77
+ end
78
+ end
79
+
80
+ def nuget_path
81
+ File.expand_path(File.join('build', 'tools', 'nuget', 'NuGet.exe'))
82
+ end
83
+
84
+ end
85
+
86
+ end