rake-funnel 0.0.1.pre
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.travis.yml +21 -0
- data/Gemfile +29 -0
- data/Guardfile +24 -0
- data/README.md +29 -0
- data/Rakefile +77 -0
- data/build.cmd +30 -0
- data/bundle.cmd +26 -0
- data/config/.gitignore +1 -0
- data/config/.local.yaml.example +9 -0
- data/config/default.yaml +5 -0
- data/config/dev.yaml +0 -0
- data/config/production.yaml +3 -0
- data/lib/rake/funnel/ambiguous_file_error.rb +29 -0
- data/lib/rake/funnel/execution_error.rb +26 -0
- data/lib/rake/funnel/extensions/camel_case.rb +19 -0
- data/lib/rake/funnel/extensions/common_path.rb +52 -0
- data/lib/rake/funnel/extensions/disable_colors.rb +27 -0
- data/lib/rake/funnel/extensions/rexml.rb +23 -0
- data/lib/rake/funnel/extensions/shell.rb +56 -0
- data/lib/rake/funnel/framework.rb +15 -0
- data/lib/rake/funnel/integration/progress_report.rb +70 -0
- data/lib/rake/funnel/integration/sync_output.rb +8 -0
- data/lib/rake/funnel/integration/teamcity/nunit_plugin.rb +59 -0
- data/lib/rake/funnel/integration/teamcity/progress_report.rb +33 -0
- data/lib/rake/funnel/integration/teamcity/service_messages.rb +40 -0
- data/lib/rake/funnel/integration/teamcity/teamcity.rb +15 -0
- data/lib/rake/funnel/integration/teamcity.rb +5 -0
- data/lib/rake/funnel/support/finder.rb +51 -0
- data/lib/rake/funnel/support/mapper.rb +81 -0
- data/lib/rake/funnel/support/mapper_styles/default.rb +31 -0
- data/lib/rake/funnel/support/mapper_styles/msbuild.rb +33 -0
- data/lib/rake/funnel/support/mapper_styles/msdeploy.rb +47 -0
- data/lib/rake/funnel/support/mapper_styles/nunit.rb +33 -0
- data/lib/rake/funnel/support/mono.rb +17 -0
- data/lib/rake/funnel/support/patch.rb +37 -0
- data/lib/rake/funnel/support/template_engine.rb +26 -0
- data/lib/rake/funnel/support/which.rb +15 -0
- data/lib/rake/funnel/tasks/bin_path.rb +34 -0
- data/lib/rake/funnel/tasks/copy.rb +54 -0
- data/lib/rake/funnel/tasks/environments.rb +74 -0
- data/lib/rake/funnel/tasks/environments_support/loader.rb +37 -0
- data/lib/rake/funnel/tasks/msbuild.rb +52 -0
- data/lib/rake/funnel/tasks/msbuild_support/build_tool.rb +28 -0
- data/lib/rake/funnel/tasks/msdeploy.rb +58 -0
- data/lib/rake/funnel/tasks/msdeploy_support/registry_patch.rb +84 -0
- data/lib/rake/funnel/tasks/nunit.rb +46 -0
- data/lib/rake/funnel/tasks/paket.rb +39 -0
- data/lib/rake/funnel/tasks/quick_template.rb +45 -0
- data/lib/rake/funnel/tasks/side_by_side_specs.rb +33 -0
- data/lib/rake/funnel/tasks/side_by_side_specs_support/remover.rb +62 -0
- data/lib/rake/funnel/tasks/timing.rb +100 -0
- data/lib/rake/funnel/tasks/timing_support/report.rb +89 -0
- data/lib/rake/funnel/tasks/timing_support/statistics.rb +26 -0
- data/lib/rake/funnel/tasks/zip.rb +66 -0
- data/lib/rake/funnel/version.rb +5 -0
- data/lib/rake/funnel.rb +7 -0
- data/rake-funnel.gemspec +28 -0
- data/spec/rake/funnel/execution_error_spec.rb +67 -0
- data/spec/rake/funnel/extensions/camel_case_spec.rb +17 -0
- data/spec/rake/funnel/extensions/common_path_spec.rb +56 -0
- data/spec/rake/funnel/extensions/disable_colors_spec.rb +33 -0
- data/spec/rake/funnel/extensions/rexml_spec.rb +20 -0
- data/spec/rake/funnel/extensions/shell_spec.rb +237 -0
- data/spec/rake/funnel/integration/progress_report_spec.rb +149 -0
- data/spec/rake/funnel/integration/sync_output_spec.rb +16 -0
- data/spec/rake/funnel/integration/teamcity/nunit_plugin_spec.rb +112 -0
- data/spec/rake/funnel/integration/teamcity/progress_report_spec.rb +174 -0
- data/spec/rake/funnel/integration/teamcity/service_messages_spec.rb +136 -0
- data/spec/rake/funnel/integration/teamcity/teamcity_spec.rb +34 -0
- data/spec/rake/funnel/support/finder_spec.rb +210 -0
- data/spec/rake/funnel/support/mapper_spec.rb +87 -0
- data/spec/rake/funnel/support/mapper_styles/msdeploy_spec.rb +222 -0
- data/spec/rake/funnel/support/mapper_styles/nunit_spec.rb +25 -0
- data/spec/rake/funnel/support/mapper_styles/styles_spec.rb +214 -0
- data/spec/rake/funnel/support/mono_spec.rb +57 -0
- data/spec/rake/funnel/support/patch_spec.rb +108 -0
- data/spec/rake/funnel/support/template_engine_spec.rb +65 -0
- data/spec/rake/funnel/support/which_spec.rb +65 -0
- data/spec/rake/funnel/tasks/bin_path_spec.rb +40 -0
- data/spec/rake/funnel/tasks/copy_spec.rb +101 -0
- data/spec/rake/funnel/tasks/environments_spec.rb +237 -0
- data/spec/rake/funnel/tasks/environments_support/loader_spec.rb +114 -0
- data/spec/rake/funnel/tasks/msbuild_spec.rb +91 -0
- data/spec/rake/funnel/tasks/msbuild_support/build_tool_spec.rb +21 -0
- data/spec/rake/funnel/tasks/msdeploy_spec.rb +243 -0
- data/spec/rake/funnel/tasks/msdeploy_support/registry_patch_spec.rb +139 -0
- data/spec/rake/funnel/tasks/nunit_spec.rb +76 -0
- data/spec/rake/funnel/tasks/paket_spec.rb +184 -0
- data/spec/rake/funnel/tasks/quick_template_spec.rb +89 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_spec.rb +58 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooCode.cs +0 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooSpecs.cs +0 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Sample.csproj +28 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Specs.cs +0 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarCode.cs +0 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarSpecs.cs +0 -0
- data/spec/rake/funnel/tasks/side_by_side_specs_support/remover_spec.rb +116 -0
- data/spec/rake/funnel/tasks/timing_spec.rb +133 -0
- data/spec/rake/funnel/tasks/timing_support/report_spec.rb +129 -0
- data/spec/rake/funnel/tasks/zip_spec.rb +119 -0
- data/spec/spec_helper.rb +32 -0
- data/tools/MSDeploy/Microsoft.Web.Delegation.dll +0 -0
- data/tools/MSDeploy/Microsoft.Web.Deployment.Tracing.dll +0 -0
- data/tools/MSDeploy/Microsoft.Web.Deployment.dll +0 -0
- data/tools/MSDeploy/en/msdeploy.resources.dll +0 -0
- data/tools/MSDeploy/msdeploy.exe +0 -0
- data/tools/MSDeploy/msdeploy.exe.config +6 -0
- metadata +253 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
Dir["#{File.dirname(__FILE__)}/msbuild_support/*.rb"].each do |path|
|
4
|
+
require path
|
5
|
+
end
|
6
|
+
|
7
|
+
module Rake::Funnel::Tasks
|
8
|
+
class MSBuild < Rake::TaskLib
|
9
|
+
attr_accessor :name, :project_or_solution, :args, :search_pattern
|
10
|
+
|
11
|
+
def initialize(name = :compile)
|
12
|
+
@name = name
|
13
|
+
@args = {}
|
14
|
+
@search_pattern = %w(**/*.sln)
|
15
|
+
|
16
|
+
yield self if block_given?
|
17
|
+
define
|
18
|
+
end
|
19
|
+
|
20
|
+
def msbuild
|
21
|
+
@_msbuild || MSBuildSupport::BuildTool.find
|
22
|
+
end
|
23
|
+
|
24
|
+
def msbuild=(value)
|
25
|
+
@_msbuild = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def project_or_solution
|
29
|
+
Rake::Funnel::Support::Finder.new(@_project_or_solution || search_pattern, self, 'No projects or more than one project found.')
|
30
|
+
end
|
31
|
+
|
32
|
+
def project_or_solution=(value)
|
33
|
+
@_project_or_solution = value
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def define
|
38
|
+
desc "Compile #{project_or_solution.single_or_default}"
|
39
|
+
task @name do
|
40
|
+
cmd = [
|
41
|
+
msbuild,
|
42
|
+
project_or_solution.single,
|
43
|
+
*Rake::Funnel::Support::Mapper.new(:MSBuild).map(args)
|
44
|
+
]
|
45
|
+
|
46
|
+
sh(*cmd)
|
47
|
+
end
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Rake::Funnel::Tasks::MSBuildSupport
|
2
|
+
class BuildTool
|
3
|
+
class << self
|
4
|
+
def find
|
5
|
+
if Rake::Win32.windows?
|
6
|
+
require 'win32/registry'
|
7
|
+
|
8
|
+
%w{12.0 4.0 3.5 2.0}.collect { |version|
|
9
|
+
msbuild = nil
|
10
|
+
key = "SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\#{version}"
|
11
|
+
|
12
|
+
begin
|
13
|
+
Win32::Registry::HKEY_LOCAL_MACHINE.open(key) do |reg|
|
14
|
+
candidate = "#{reg['MSBuildToolsPath']}\\msbuild.exe"
|
15
|
+
msbuild = candidate if File.exists?(candidate)
|
16
|
+
end
|
17
|
+
rescue
|
18
|
+
end
|
19
|
+
|
20
|
+
msbuild
|
21
|
+
}.compact.first
|
22
|
+
else
|
23
|
+
'xbuild'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
Dir["#{File.dirname(__FILE__)}/msdeploy_support/*.rb"].each do |path|
|
5
|
+
require path
|
6
|
+
end
|
7
|
+
|
8
|
+
module Rake::Funnel::Tasks
|
9
|
+
class MSDeploy < Rake::TaskLib
|
10
|
+
attr_accessor :name, :msdeploy, :log_file, :args
|
11
|
+
|
12
|
+
def initialize(name = :msdeploy)
|
13
|
+
@name = name
|
14
|
+
@msdeploy = 'msdeploy'
|
15
|
+
@args = {}
|
16
|
+
|
17
|
+
yield self if block_given?
|
18
|
+
define
|
19
|
+
end
|
20
|
+
|
21
|
+
def log_file
|
22
|
+
@log_file || "#{@name}.log"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def define
|
27
|
+
CLEAN.include(log_file)
|
28
|
+
|
29
|
+
desc "Deploy #{deploy_source(args)}"
|
30
|
+
task @name do
|
31
|
+
mapper = Rake::Funnel::Support::Mapper.new(:MSDeploy)
|
32
|
+
cmd = [quote(msdeploy), mapper.map(args)]
|
33
|
+
.flatten
|
34
|
+
.join(' ')
|
35
|
+
|
36
|
+
MSDeploySupport::RegistryPatch.new do
|
37
|
+
shell(cmd, log_file: log_file, error_lines: /^(error|[\w\.]*exception)/i)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def deploy_source(args)
|
45
|
+
source = (args || {}).fetch(:source, {})
|
46
|
+
path = source.first
|
47
|
+
return if path.nil?
|
48
|
+
|
49
|
+
Pathname.new(path[1]).relative_path_from(Pathname.new('.').realpath) rescue path[1]
|
50
|
+
end
|
51
|
+
|
52
|
+
def quote(value)
|
53
|
+
value = value.gsub(/"/, '""') if value.kind_of?(String)
|
54
|
+
return %Q{"#{value}"} if value =~ /\s/
|
55
|
+
value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Rake::Funnel::Tasks::MSDeploySupport
|
2
|
+
class RegistryPatch
|
3
|
+
KEYS = [
|
4
|
+
'SOFTWARE\Microsoft\IIS Extensions\MSDeploy\3',
|
5
|
+
'SOFTWARE\Wow6432Node\Microsoft\IIS Extensions\MSDeploy\3'
|
6
|
+
]
|
7
|
+
VERSION_VALUE = 'Version'
|
8
|
+
FAKE_VERSION = '99.0.0.0'
|
9
|
+
|
10
|
+
def initialize(&block)
|
11
|
+
begin
|
12
|
+
patch.apply!
|
13
|
+
yield block if block_given?
|
14
|
+
ensure
|
15
|
+
patch.revert!
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def patch
|
21
|
+
@patch ||= create_patch
|
22
|
+
end
|
23
|
+
|
24
|
+
def root
|
25
|
+
Win32::Registry::HKEY_LOCAL_MACHINE
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete_key(key)
|
29
|
+
return nil unless key.created?
|
30
|
+
|
31
|
+
keyname = key.keyname
|
32
|
+
Proc.new {
|
33
|
+
root.create(File.dirname(keyname)) do |r|
|
34
|
+
r.delete_key(File.basename(keyname), true)
|
35
|
+
end
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def delete_value(key, value)
|
40
|
+
keyname = key.keyname
|
41
|
+
Proc.new {
|
42
|
+
root.create(keyname) do |r|
|
43
|
+
r.delete_value(value)
|
44
|
+
end
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_patch
|
49
|
+
begin
|
50
|
+
require 'win32/registry'
|
51
|
+
rescue LoadError
|
52
|
+
return Rake::Funnel::Support::Patch.new(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
Rake::Funnel::Support::Patch.new(self) do |p|
|
56
|
+
resets = []
|
57
|
+
|
58
|
+
p.setup do
|
59
|
+
resets = KEYS.map do |key|
|
60
|
+
root.create(key) do |r|
|
61
|
+
begin
|
62
|
+
r[VERSION_VALUE]
|
63
|
+
|
64
|
+
delete_version = Proc.new {}
|
65
|
+
rescue Win32::Registry::Error
|
66
|
+
r[VERSION_VALUE] = FAKE_VERSION
|
67
|
+
|
68
|
+
delete_version = delete_value(r, VERSION_VALUE)
|
69
|
+
end
|
70
|
+
|
71
|
+
delete_key(r) || delete_version
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
p.reset do
|
77
|
+
resets.compact.each do |reset|
|
78
|
+
reset.call
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
module Rake::Funnel::Tasks
|
4
|
+
class NUnit < Rake::TaskLib
|
5
|
+
attr_accessor :name, :files, :args
|
6
|
+
|
7
|
+
def initialize(name = :test)
|
8
|
+
@name = name
|
9
|
+
@args = {}
|
10
|
+
@files = %w(build/specs/**/*.dll build/specs/**/*.exe)
|
11
|
+
|
12
|
+
yield self if block_given?
|
13
|
+
define
|
14
|
+
end
|
15
|
+
|
16
|
+
def nunit
|
17
|
+
@_nunit || 'nunit-console.exe'
|
18
|
+
end
|
19
|
+
|
20
|
+
def nunit=(value)
|
21
|
+
@_nunit = value
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def define
|
26
|
+
desc "Test #{test_assemblies.all_or_default.join(', ')}"
|
27
|
+
task name do
|
28
|
+
Rake::Funnel::Integration::TeamCity::NUnitPlugin.setup(nunit)
|
29
|
+
|
30
|
+
cmd = [
|
31
|
+
*Rake::Funnel::Support::Mono.invocation(nunit),
|
32
|
+
*test_assemblies.all,
|
33
|
+
*Rake::Funnel::Support::Mapper.new(:NUnit).map(args)
|
34
|
+
]
|
35
|
+
|
36
|
+
sh(*cmd)
|
37
|
+
end
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_assemblies
|
43
|
+
Rake::Funnel::Support::Finder.new(files, self, 'No test assemblies found.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
module Rake::Funnel::Tasks
|
4
|
+
class Paket < Rake::TaskLib
|
5
|
+
attr_accessor :name, :paket, :paket_args, :bootstrapper, :bootstrapper_args
|
6
|
+
|
7
|
+
def initialize(name = :paket)
|
8
|
+
@name = name
|
9
|
+
|
10
|
+
@paket = File.join('.paket', 'paket.exe')
|
11
|
+
@paket_args = 'restore'
|
12
|
+
|
13
|
+
@bootstrapper = File.join('.paket', 'paket.bootstrapper.exe')
|
14
|
+
@bootstrapper_args = nil
|
15
|
+
|
16
|
+
yield self if block_given?
|
17
|
+
define
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def define
|
22
|
+
desc "#{paket_cmd.join(' ')} (optionally #{bootstrapper_cmd.join(' ')})"
|
23
|
+
task name do
|
24
|
+
sh(*bootstrapper_cmd) unless File.exist?(paket)
|
25
|
+
sh(*paket_cmd)
|
26
|
+
end
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def bootstrapper_cmd
|
32
|
+
Rake::Funnel::Support::Mono.invocation(bootstrapper, bootstrapper_args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def paket_cmd
|
36
|
+
Rake::Funnel::Support::Mono.invocation(paket, paket_args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
module Rake::Funnel::Tasks
|
5
|
+
class QuickTemplate < Rake::TaskLib
|
6
|
+
attr_accessor :name, :search_pattern, :context
|
7
|
+
|
8
|
+
def initialize(name = :template)
|
9
|
+
@name = name
|
10
|
+
|
11
|
+
@search_pattern = %w(**/*.template)
|
12
|
+
@context = binding
|
13
|
+
|
14
|
+
yield self if block_given?
|
15
|
+
define
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def define
|
20
|
+
results = templates.all_or_default.map { |t| result_filename(t) }
|
21
|
+
CLEAN.include(*results)
|
22
|
+
|
23
|
+
desc "Generate #{templates.all_or_default.join(', ')}"
|
24
|
+
task name do
|
25
|
+
templates.all_or_default.each do |template|
|
26
|
+
target = result_filename(template)
|
27
|
+
Rake.rake_output_message "Creating file #{target}"
|
28
|
+
|
29
|
+
content = Rake::Funnel::Support::TemplateEngine.render(File.read(template), template, context)
|
30
|
+
File.write(target, content)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def templates
|
38
|
+
Rake::Funnel::Support::Finder.new(search_pattern, self, 'No templates found.')
|
39
|
+
end
|
40
|
+
|
41
|
+
def result_filename(template)
|
42
|
+
template.ext
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
Dir["#{File.dirname(__FILE__)}/side_by_side_specs_support/*.rb"].each do |path|
|
4
|
+
require path
|
5
|
+
end
|
6
|
+
|
7
|
+
module Rake::Funnel::Tasks
|
8
|
+
class SideBySideSpecs < Rake::TaskLib
|
9
|
+
attr_accessor :name, :projects, :references, :specs, :enabled
|
10
|
+
|
11
|
+
def initialize(name = :compile)
|
12
|
+
@name = name
|
13
|
+
|
14
|
+
@projects = %w(**/*.csproj **/*.vbproj **/*.fsproj)
|
15
|
+
@references = []
|
16
|
+
@specs = %w(*Specs.cs **/*Specs.cs *Tests.cs **/*Tests.cs)
|
17
|
+
@enabled = false
|
18
|
+
|
19
|
+
yield self if block_given?
|
20
|
+
define
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def define
|
25
|
+
task name do
|
26
|
+
next unless enabled
|
27
|
+
SideBySideSpecsSupport::Remover.remove({ projects: projects, references: references, specs: specs })
|
28
|
+
end
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Rake::Funnel::Tasks::SideBySideSpecsSupport
|
4
|
+
class Remover
|
5
|
+
class << self
|
6
|
+
DEFAULTS = {
|
7
|
+
projects: [],
|
8
|
+
references: [],
|
9
|
+
specs: []
|
10
|
+
}
|
11
|
+
|
12
|
+
def remove(args = {})
|
13
|
+
args = DEFAULTS.merge(args)
|
14
|
+
|
15
|
+
projects(args).each do |project|
|
16
|
+
xml = REXML::Document.new(File.read(project), { attribute_quote: :quote })
|
17
|
+
|
18
|
+
removed = remove_references(args, xml) + remove_specs(args, xml)
|
19
|
+
|
20
|
+
write_xml(project, xml) if removed.flatten.any?
|
21
|
+
end
|
22
|
+
|
23
|
+
delete_specs(args)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def write_xml(project, xml)
|
28
|
+
File.open(project, 'w+') do |file|
|
29
|
+
xml.write(output: file, ie_hack: true)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete_specs(args)
|
34
|
+
Dir[*args[:specs]].uniq.each do |spec|
|
35
|
+
RakeFileUtils.rm(spec)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def projects(args)
|
40
|
+
Dir[*args[:projects]]
|
41
|
+
end
|
42
|
+
|
43
|
+
def list(args)
|
44
|
+
([] << args).flatten
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_references(args, xml)
|
48
|
+
list(args[:references]).map do |ref|
|
49
|
+
query = "/Project//Reference[starts-with(lower-case(@Include), '#{ref.downcase}')]"
|
50
|
+
xml.elements.delete_all(query)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_specs(args, xml)
|
55
|
+
list(args[:specs]).map do |glob|
|
56
|
+
query = "/Project//Compile[matches(lower-case(@Include), '#{glob}')]"
|
57
|
+
xml.elements.delete_all(query)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
Dir["#{File.dirname(__FILE__)}/timing_support/*.rb"].each do |path|
|
5
|
+
require path
|
6
|
+
end
|
7
|
+
|
8
|
+
module Rake::Funnel::Tasks
|
9
|
+
class Timing < Rake::TaskLib
|
10
|
+
attr_accessor :name
|
11
|
+
attr_reader :stats
|
12
|
+
|
13
|
+
def initialize(name = :timing)
|
14
|
+
@name = name
|
15
|
+
@stats = TimingSupport::Statistics.new
|
16
|
+
|
17
|
+
yield self if block_given?
|
18
|
+
|
19
|
+
define
|
20
|
+
end
|
21
|
+
|
22
|
+
def reset!
|
23
|
+
patches.each { |p| p.revert! }
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def define
|
28
|
+
patches.each { |p| p.apply! }
|
29
|
+
|
30
|
+
task @name, :failed do |task, args|
|
31
|
+
TimingSupport::Report.new(@stats, args).render
|
32
|
+
end
|
33
|
+
|
34
|
+
timing_task = Rake.application.current_scope.path_with_task_name(@name)
|
35
|
+
Rake.application.top_level_tasks.push(timing_task)
|
36
|
+
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def patches
|
41
|
+
@patches ||= create_patches
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_patches
|
45
|
+
report = Rake::Funnel::Support::Patch.new do |p|
|
46
|
+
report_invoker = -> (opts) { TimingSupport::Report.new(@stats, opts).render }
|
47
|
+
|
48
|
+
p.setup do
|
49
|
+
Rake::Application.class_eval do
|
50
|
+
orig_display_error_message = instance_method(:display_error_message)
|
51
|
+
|
52
|
+
define_method(:display_error_message) do |ex|
|
53
|
+
orig_display_error_message.bind(self).call(ex)
|
54
|
+
|
55
|
+
report_invoker.call(failed: true)
|
56
|
+
end
|
57
|
+
|
58
|
+
orig_display_error_message
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
p.reset do |memo|
|
63
|
+
Rake::Application.class_eval do
|
64
|
+
define_method(:display_error_message) do |ex|
|
65
|
+
memo.bind(self).call(ex)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
benchmark = Rake::Funnel::Support::Patch.new do |p|
|
72
|
+
benchmark_invoker = -> (task, &block) { @stats.benchmark(task, &block) }
|
73
|
+
|
74
|
+
p.setup do
|
75
|
+
Rake::Task.class_eval do
|
76
|
+
orig_execute = instance_method(:execute)
|
77
|
+
|
78
|
+
define_method(:execute) do |args|
|
79
|
+
benchmark_invoker.call(self) do
|
80
|
+
orig_execute.bind(self).call(args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
orig_execute
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
p.reset do |memo|
|
89
|
+
Rake::Task.class_eval do
|
90
|
+
define_method(:execute) do |ex|
|
91
|
+
memo.bind(self).call(ex)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
[report, benchmark]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'smart_colored/extend'
|
2
|
+
|
3
|
+
module Rake::Funnel::Tasks::TimingSupport
|
4
|
+
class Report
|
5
|
+
class Column
|
6
|
+
attr_reader :header
|
7
|
+
|
8
|
+
def initialize(stats: [], header: '', accessor: -> (_) { '' })
|
9
|
+
@stats = stats
|
10
|
+
@header = header
|
11
|
+
@accessor = accessor
|
12
|
+
end
|
13
|
+
|
14
|
+
def width
|
15
|
+
longest_value = @stats.map { |s| @accessor.call(s) }.max_by { |m| m.length } || ''
|
16
|
+
width = longest_value.length
|
17
|
+
width = @header.length if width < @header.length
|
18
|
+
width
|
19
|
+
end
|
20
|
+
|
21
|
+
def format_header
|
22
|
+
@header.ljust(width)
|
23
|
+
end
|
24
|
+
|
25
|
+
def format_value(value)
|
26
|
+
@accessor.call(value).ljust(width)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
SPACE = 3
|
31
|
+
HEADER_WIDTH = 70
|
32
|
+
|
33
|
+
def initialize(stats, opts = {})
|
34
|
+
@stats = stats
|
35
|
+
@opts = opts
|
36
|
+
end
|
37
|
+
|
38
|
+
def render
|
39
|
+
header
|
40
|
+
rows
|
41
|
+
footer
|
42
|
+
end
|
43
|
+
|
44
|
+
def columns
|
45
|
+
@columns ||= ([
|
46
|
+
Column.new(stats: @stats, header: 'Target', accessor: -> (timing) { timing[:task].name }),
|
47
|
+
Column.new(stats: @stats, header: 'Duration', accessor: -> (timing) { format(timing[:time]) })
|
48
|
+
])
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def header
|
53
|
+
puts '-' * HEADER_WIDTH
|
54
|
+
puts 'Build time report'
|
55
|
+
puts '-' * HEADER_WIDTH
|
56
|
+
|
57
|
+
puts columns.map { |c| c.format_header }.join(' ' * SPACE)
|
58
|
+
puts columns.map { |c| c.format_header.gsub(/./, '-') }.join(' ' * SPACE)
|
59
|
+
end
|
60
|
+
|
61
|
+
def rows
|
62
|
+
@stats.each do |timing|
|
63
|
+
puts columns.map { |c| c.format_value(timing) }.join(' ' * SPACE)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def footer
|
68
|
+
puts '-' * HEADER_WIDTH
|
69
|
+
puts 'Total'.ljust(columns[0].width) + ' ' * SPACE + format(Time.now - @stats.started_at)
|
70
|
+
status_message
|
71
|
+
puts '-' * HEADER_WIDTH
|
72
|
+
end
|
73
|
+
|
74
|
+
def format(seconds)
|
75
|
+
Time.at(seconds).utc.strftime('%H:%M:%S')
|
76
|
+
end
|
77
|
+
|
78
|
+
def status_message
|
79
|
+
status = @opts[:failed] ? 'Failed' : 'OK'
|
80
|
+
status = 'Status'.ljust(columns[0].width) + ' ' * SPACE + status
|
81
|
+
|
82
|
+
if @opts[:failed]
|
83
|
+
$stderr.puts status.bold.red
|
84
|
+
else
|
85
|
+
$stdout.puts status.bold.green
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rake::Funnel::Tasks::TimingSupport
|
2
|
+
class Statistics
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :started_at
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@stats = []
|
9
|
+
@started_at = Time.now
|
10
|
+
end
|
11
|
+
|
12
|
+
def each(&block)
|
13
|
+
@stats.each(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def benchmark(task)
|
17
|
+
t0 = Time.now
|
18
|
+
begin
|
19
|
+
yield if block_given?
|
20
|
+
ensure
|
21
|
+
t1 = Time.now
|
22
|
+
@stats << { task: task, time: t1 - t0 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|