bozo-scripts 0.1.5 → 0.1.6

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