rake-funnel 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +21 -0
  5. data/Gemfile +29 -0
  6. data/Guardfile +24 -0
  7. data/README.md +29 -0
  8. data/Rakefile +77 -0
  9. data/build.cmd +30 -0
  10. data/bundle.cmd +26 -0
  11. data/config/.gitignore +1 -0
  12. data/config/.local.yaml.example +9 -0
  13. data/config/default.yaml +5 -0
  14. data/config/dev.yaml +0 -0
  15. data/config/production.yaml +3 -0
  16. data/lib/rake/funnel/ambiguous_file_error.rb +29 -0
  17. data/lib/rake/funnel/execution_error.rb +26 -0
  18. data/lib/rake/funnel/extensions/camel_case.rb +19 -0
  19. data/lib/rake/funnel/extensions/common_path.rb +52 -0
  20. data/lib/rake/funnel/extensions/disable_colors.rb +27 -0
  21. data/lib/rake/funnel/extensions/rexml.rb +23 -0
  22. data/lib/rake/funnel/extensions/shell.rb +56 -0
  23. data/lib/rake/funnel/framework.rb +15 -0
  24. data/lib/rake/funnel/integration/progress_report.rb +70 -0
  25. data/lib/rake/funnel/integration/sync_output.rb +8 -0
  26. data/lib/rake/funnel/integration/teamcity/nunit_plugin.rb +59 -0
  27. data/lib/rake/funnel/integration/teamcity/progress_report.rb +33 -0
  28. data/lib/rake/funnel/integration/teamcity/service_messages.rb +40 -0
  29. data/lib/rake/funnel/integration/teamcity/teamcity.rb +15 -0
  30. data/lib/rake/funnel/integration/teamcity.rb +5 -0
  31. data/lib/rake/funnel/support/finder.rb +51 -0
  32. data/lib/rake/funnel/support/mapper.rb +81 -0
  33. data/lib/rake/funnel/support/mapper_styles/default.rb +31 -0
  34. data/lib/rake/funnel/support/mapper_styles/msbuild.rb +33 -0
  35. data/lib/rake/funnel/support/mapper_styles/msdeploy.rb +47 -0
  36. data/lib/rake/funnel/support/mapper_styles/nunit.rb +33 -0
  37. data/lib/rake/funnel/support/mono.rb +17 -0
  38. data/lib/rake/funnel/support/patch.rb +37 -0
  39. data/lib/rake/funnel/support/template_engine.rb +26 -0
  40. data/lib/rake/funnel/support/which.rb +15 -0
  41. data/lib/rake/funnel/tasks/bin_path.rb +34 -0
  42. data/lib/rake/funnel/tasks/copy.rb +54 -0
  43. data/lib/rake/funnel/tasks/environments.rb +74 -0
  44. data/lib/rake/funnel/tasks/environments_support/loader.rb +37 -0
  45. data/lib/rake/funnel/tasks/msbuild.rb +52 -0
  46. data/lib/rake/funnel/tasks/msbuild_support/build_tool.rb +28 -0
  47. data/lib/rake/funnel/tasks/msdeploy.rb +58 -0
  48. data/lib/rake/funnel/tasks/msdeploy_support/registry_patch.rb +84 -0
  49. data/lib/rake/funnel/tasks/nunit.rb +46 -0
  50. data/lib/rake/funnel/tasks/paket.rb +39 -0
  51. data/lib/rake/funnel/tasks/quick_template.rb +45 -0
  52. data/lib/rake/funnel/tasks/side_by_side_specs.rb +33 -0
  53. data/lib/rake/funnel/tasks/side_by_side_specs_support/remover.rb +62 -0
  54. data/lib/rake/funnel/tasks/timing.rb +100 -0
  55. data/lib/rake/funnel/tasks/timing_support/report.rb +89 -0
  56. data/lib/rake/funnel/tasks/timing_support/statistics.rb +26 -0
  57. data/lib/rake/funnel/tasks/zip.rb +66 -0
  58. data/lib/rake/funnel/version.rb +5 -0
  59. data/lib/rake/funnel.rb +7 -0
  60. data/rake-funnel.gemspec +28 -0
  61. data/spec/rake/funnel/execution_error_spec.rb +67 -0
  62. data/spec/rake/funnel/extensions/camel_case_spec.rb +17 -0
  63. data/spec/rake/funnel/extensions/common_path_spec.rb +56 -0
  64. data/spec/rake/funnel/extensions/disable_colors_spec.rb +33 -0
  65. data/spec/rake/funnel/extensions/rexml_spec.rb +20 -0
  66. data/spec/rake/funnel/extensions/shell_spec.rb +237 -0
  67. data/spec/rake/funnel/integration/progress_report_spec.rb +149 -0
  68. data/spec/rake/funnel/integration/sync_output_spec.rb +16 -0
  69. data/spec/rake/funnel/integration/teamcity/nunit_plugin_spec.rb +112 -0
  70. data/spec/rake/funnel/integration/teamcity/progress_report_spec.rb +174 -0
  71. data/spec/rake/funnel/integration/teamcity/service_messages_spec.rb +136 -0
  72. data/spec/rake/funnel/integration/teamcity/teamcity_spec.rb +34 -0
  73. data/spec/rake/funnel/support/finder_spec.rb +210 -0
  74. data/spec/rake/funnel/support/mapper_spec.rb +87 -0
  75. data/spec/rake/funnel/support/mapper_styles/msdeploy_spec.rb +222 -0
  76. data/spec/rake/funnel/support/mapper_styles/nunit_spec.rb +25 -0
  77. data/spec/rake/funnel/support/mapper_styles/styles_spec.rb +214 -0
  78. data/spec/rake/funnel/support/mono_spec.rb +57 -0
  79. data/spec/rake/funnel/support/patch_spec.rb +108 -0
  80. data/spec/rake/funnel/support/template_engine_spec.rb +65 -0
  81. data/spec/rake/funnel/support/which_spec.rb +65 -0
  82. data/spec/rake/funnel/tasks/bin_path_spec.rb +40 -0
  83. data/spec/rake/funnel/tasks/copy_spec.rb +101 -0
  84. data/spec/rake/funnel/tasks/environments_spec.rb +237 -0
  85. data/spec/rake/funnel/tasks/environments_support/loader_spec.rb +114 -0
  86. data/spec/rake/funnel/tasks/msbuild_spec.rb +91 -0
  87. data/spec/rake/funnel/tasks/msbuild_support/build_tool_spec.rb +21 -0
  88. data/spec/rake/funnel/tasks/msdeploy_spec.rb +243 -0
  89. data/spec/rake/funnel/tasks/msdeploy_support/registry_patch_spec.rb +139 -0
  90. data/spec/rake/funnel/tasks/nunit_spec.rb +76 -0
  91. data/spec/rake/funnel/tasks/paket_spec.rb +184 -0
  92. data/spec/rake/funnel/tasks/quick_template_spec.rb +89 -0
  93. data/spec/rake/funnel/tasks/side_by_side_specs_spec.rb +58 -0
  94. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooCode.cs +0 -0
  95. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/FooSpecs.cs +0 -0
  96. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Sample.csproj +28 -0
  97. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/Specs.cs +0 -0
  98. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarCode.cs +0 -0
  99. data/spec/rake/funnel/tasks/side_by_side_specs_support/example/subdir/BarSpecs.cs +0 -0
  100. data/spec/rake/funnel/tasks/side_by_side_specs_support/remover_spec.rb +116 -0
  101. data/spec/rake/funnel/tasks/timing_spec.rb +133 -0
  102. data/spec/rake/funnel/tasks/timing_support/report_spec.rb +129 -0
  103. data/spec/rake/funnel/tasks/zip_spec.rb +119 -0
  104. data/spec/spec_helper.rb +32 -0
  105. data/tools/MSDeploy/Microsoft.Web.Delegation.dll +0 -0
  106. data/tools/MSDeploy/Microsoft.Web.Deployment.Tracing.dll +0 -0
  107. data/tools/MSDeploy/Microsoft.Web.Deployment.dll +0 -0
  108. data/tools/MSDeploy/en/msdeploy.resources.dll +0 -0
  109. data/tools/MSDeploy/msdeploy.exe +0 -0
  110. data/tools/MSDeploy/msdeploy.exe.config +6 -0
  111. metadata +253 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d13cf1a193e9b4f8f63bf3845a7b9e3411dc6b77
4
+ data.tar.gz: 83dcbb1be8a17e1b7b8b6065a69868d550ca2c71
5
+ SHA512:
6
+ metadata.gz: a082174a5f60488ae61a0319fbc0e793073b92f7a5363161d9f57e28ef86325ed51d6d953824d132b9f31d11596700d7978e6931abcfdf8a3c9c572d5a197738
7
+ data.tar.gz: 1bb7a3277da0c4c7a0b49f411abea297bc3fae354fbce34bbddc056dcdc71109ec695439a2a7d2a48018d3ae70bab20207b7e678720e8f30525a6d30a876818a
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .idea/
2
+ build/
3
+ deploy/
4
+ tmp/
5
+
6
+ Gemfile.lock
7
+ cacert.pem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --tag ~@draft
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ script: bundle exec rspec --tag ~platform:win32
4
+ rvm:
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - 2.1.1
8
+ - 2.1.2
9
+ - 2.1.3
10
+ - 2.1.4
11
+ - 2.1.5
12
+ - 2.2.0
13
+ - ruby-head
14
+ notifications:
15
+ email:
16
+ recipients:
17
+ - agross@therightstuff.de
18
+ on_success: never
19
+ addons:
20
+ code_climate:
21
+ repo_token: d8b15ab15f45f543f1ddd59b4224f83e6fcc9576f2fa4ba2817ae20d445f5f4f
data/Gemfile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rbconfig'
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development do
8
+ gem 'guard-bundler', require: false
9
+ gem 'guard-rspec', require: false
10
+
11
+ case RbConfig::CONFIG['target_os']
12
+ when /windows|bccwin|cygwin|djgpp|mingw|mswin|wince/i
13
+ gem 'ruby_gntp', require: false
14
+ gem 'wdm', require: false
15
+ when /linux/i
16
+ gem 'rb-inotify', require: false
17
+ when /mac|darwin/i
18
+ gem 'rb-fsevent', require: false
19
+ gem 'growl', require: false
20
+ end
21
+ end
22
+
23
+ group :development, :ci do
24
+ gem 'rspec', '~> 3.0', require: false
25
+ gem 'rspec-its', require: false
26
+ gem 'rspec-collection_matchers', require: false
27
+ gem 'coveralls', require: false
28
+ gem 'codeclimate-test-reporter', require: false
29
+ end
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ case RbConfig::CONFIG['target_os']
2
+ when /windows|bccwin|cygwin|djgpp|mingw|mswin|wince/i
3
+ notification :gntp, :host => 'localhost'
4
+ when /linux/i
5
+ notification :notifysend
6
+ when /mac|darwin/i
7
+ notification :growl
8
+ end
9
+
10
+ guard 'bundler' do
11
+ watch('Gemfile')
12
+ watch(/^.+\.gemspec/)
13
+ end
14
+
15
+ guard 'rspec',
16
+ :all_on_start => true,
17
+ :all_after_pass => true,
18
+ :notification => true,
19
+ :cmd => 'bundle exec rspec' do
20
+ watch('.rspec') { 'spec' }
21
+ watch(%r{^spec/.+_spec\.rb$})
22
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
23
+ watch('spec/spec_helper.rb') { 'spec' }
24
+ end
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # rake-funnel
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rake-funnel.png)](http://badge.fury.io/rb/rake-funnel) [![Build Status](https://travis-ci.org/agross/rake-funnel.png?branch=master)](https://travis-ci.org/agross/rake-funnel) [![Dependency Status](https://gemnasium.com/agross/rake-funnel.png)](https://gemnasium.com/agross/rake-funnel) [![Code Climate](https://codeclimate.com/github/agross/rake-funnel.png)](https://codeclimate.com/github/agross/rake-funnel) [![Coverage Status](https://coveralls.io/repos/agross/rake-funnel/badge.png)](https://coveralls.io/r/agross/rake-funnel)
4
+
5
+ rake-funnel is my set of rake tasks, mostly targeted at .NET development.
6
+
7
+ * Tested against Ruby 2.0.0, 2.1.0 and 2.2.0 and ruby-head
8
+ * Ruby < 2.0 is not supported
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ $ gem install rake-funnel
14
+ ```
15
+
16
+ ## Development
17
+
18
+ * Source hosted at [GitHub](https://github.com/agross/rake-funnel)
19
+ * Report issues/Questions/Feature requests on [GitHub Issues](https://github.com/agross/rake-funnel/issues)
20
+
21
+ Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change you make.
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it (http://github.com/agross/rake-funnel/fork)
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,77 @@
1
+ require 'rake/funnel'
2
+ require 'rubygems/package_task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ include Rake::Funnel
6
+
7
+ Tasks::Timing.new
8
+ Tasks::BinPath.new
9
+ Integration::SyncOutput.new
10
+ Integration::ProgressReport.new
11
+ Integration::TeamCity::ProgressReport.new
12
+
13
+ namespace :env do
14
+ Tasks::Environments.new do |t|
15
+ t.default_env = :dev
16
+ end
17
+ end
18
+
19
+ task default: :spec
20
+
21
+ RSpec::Core::RakeTask.new(:spec) do |t|
22
+ t.rspec_opts = '--order random'
23
+ if Integration::TeamCity.running?
24
+ t.rspec_opts += ' --format progress --format html --out build/spec/rspec.html'
25
+ end
26
+ t.rspec_opts += ' --tag ~platform:win32' unless Rake::Win32.windows?
27
+ end
28
+
29
+ spec = Gem::Specification.load('rake-funnel.gemspec')
30
+ gem = Gem::PackageTask.new(spec) do |t|
31
+ t.package_dir = 'deploy'
32
+
33
+ task :gem do
34
+ rm_rf t.package_dir_path
35
+ end
36
+ end
37
+
38
+ task gem: :spec do
39
+ Integration::TeamCity::ServiceMessages.build_number(spec.version.to_s)
40
+ end
41
+
42
+ Tasks::MSDeploy.new :push => [:bin_path, :gem] do |t|
43
+ gem = File.join(File.expand_path(gem.package_dir), gem.gem_spec.file_name)
44
+
45
+ t.log_file = 'deploy/msdeploy.log'
46
+ t.args = {
47
+ verb: :sync,
48
+ pre_sync: {
49
+ run_command: "mkdir #{configatron.deployment.remote_dir}\\gems",
50
+ wait_interval: 60 * 1000
51
+ },
52
+ source: {
53
+ file_path: gem
54
+ },
55
+ dest: {
56
+ computer_name: configatron.deployment.computer_name,
57
+ username: configatron.deployment.username,
58
+ password: configatron.deployment.password,
59
+ file_path: File.join(configatron.deployment.remote_dir, 'gems', File.basename(gem))
60
+ },
61
+ skip: [{ skip_action: :delete }],
62
+ post_sync_on_success: {
63
+ run_command: "gem generate_index -V --directory=#{configatron.deployment.remote_dir} & icacls #{configatron.deployment.remote_dir} /reset /t /c /q",
64
+ wait_interval: 60 * 1000
65
+ },
66
+ use_check_sum: nil,
67
+ allow_untrusted: nil
68
+ }
69
+ end
70
+
71
+ task :fail do
72
+ raise 'this build is expected to fail'
73
+ end
74
+
75
+ task :long_running do
76
+ sleep(30)
77
+ end
data/build.cmd ADDED
@@ -0,0 +1,30 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ set LANG=en_US.UTF-8
5
+
6
+ :build
7
+ cls
8
+
9
+ call bundle.cmd check
10
+ if errorlevel 1 call bundle.cmd install
11
+ if errorlevel 1 goto wait
12
+
13
+ cls
14
+
15
+ call bundle.cmd exec rake %*
16
+
17
+ :wait
18
+ rem Bail if we're running a TeamCity build.
19
+ if defined TEAMCITY_PROJECT_NAME goto quit
20
+
21
+ rem Loop the build script.
22
+ set choice=nothing
23
+ echo (Q)uit, (Enter) runs the build again
24
+ set /P choice=
25
+ if /i "%choice%"=="Q" goto quit
26
+
27
+ goto build
28
+
29
+ :quit
30
+ exit /b %errorlevel%
data/bundle.cmd ADDED
@@ -0,0 +1,26 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ set LANG=en_US.UTF-8
5
+ set PATH=%~dp0tools\Git\bin;%path%
6
+ set DOWNLOAD_CA_BUNDLE="require 'net/http'; Net::HTTP.start('curl.haxx.se') { |http| resp = http.get('/ca/cacert.pem'); abort 'Error downloading CA bundle: ' + resp.code unless resp.code == '200'; open('cacert.pem', 'wb') { |file| file.write(resp.body) }; }"
7
+
8
+ if not exist cacert.pem (
9
+ echo Downloading latest CA bundle...
10
+ ruby -e %DOWNLOAD_CA_BUNDLE%
11
+
12
+ if errorlevel 1 (
13
+ exit /b %errorlevel%
14
+ )
15
+ )
16
+
17
+ set SSL_CERT_FILE=%cd%\cacert.pem
18
+
19
+ call gem.bat which bundler > NUL 2>&1
20
+ if errorlevel 1 (
21
+ echo Installing bundler...
22
+ call gem.bat install bundler --no-ri --no-rdoc
23
+ )
24
+
25
+ call bundle.bat %*
26
+ exit /b %errorlevel%
data/config/.gitignore ADDED
@@ -0,0 +1 @@
1
+ local.yaml
@@ -0,0 +1,9 @@
1
+ # Copy this file to local.yaml and put configuration values to temporarily
2
+ # override here.
3
+ #
4
+ # Please do not add local.yaml to source control.
5
+ #
6
+ # Example:
7
+
8
+ deployment:
9
+ computer_name: somewhere-else
@@ -0,0 +1,5 @@
1
+ deployment:
2
+ computer_name: localhost
3
+ username: <%= ENV['DEPLOY_USER'] || ENV['COMPUTERNAME'] + '\Administrator' %>
4
+ password: <%= ENV['DEPLOY_PASSWORD'] %>
5
+ remote_dir: <%= (ENV['TEMP'] + '/_gems').gsub(%r|/|, '\\') %>
data/config/dev.yaml ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ deployment:
2
+ computer_name: gems.grossweber.com
3
+ remote_dir: <%= 'C:/GROSSWEBER/gems'.gsub(%r|/|, '\\') %>
@@ -0,0 +1,29 @@
1
+ module Rake::Funnel
2
+ class AmbiguousFileError < StandardError
3
+ attr_reader :task_name, :search_pattern, :candidates, :description
4
+
5
+ def initialize(message, task_name, search_pattern, candidates)
6
+ description = "Could not run task '#{task_name}'. #{message}"
7
+ super(description)
8
+
9
+ @description = description
10
+ @task_name = task_name
11
+ @search_pattern = search_pattern
12
+ @candidates = candidates
13
+ end
14
+
15
+ def to_s
16
+ msg = []
17
+ (msg << description) if description
18
+ (msg << "Search pattern used: #{@search_pattern}") if @search_pattern
19
+ unless (@candidates || []).empty?
20
+ msg << 'Candidates:'
21
+ msg << @candidates.map { |c| " - #{c}" }
22
+ end
23
+
24
+ msg = [super.to_s] if msg.empty?
25
+
26
+ msg.join("\n")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module Rake::Funnel
2
+ class ExecutionError < StandardError
3
+ attr_reader :command, :exit_code, :output, :description
4
+
5
+ def initialize(command = nil, exit_code = nil, output = nil, description = nil)
6
+ super(description)
7
+
8
+ @description = description
9
+ @command = command
10
+ @exit_code = exit_code
11
+ @output = output
12
+ end
13
+
14
+ def to_s
15
+ msg = []
16
+ (msg << description << nil) if description
17
+ (msg << 'Error executing:' << command << nil) if command
18
+ (msg << "Exit code: #{exit_code}" << nil) if exit_code
19
+ (msg << 'Command output (last 10 lines):' << output.split("\n").last(10) << nil) if output
20
+
21
+ msg = [super.to_s] if msg.empty?
22
+
23
+ msg.join("\n")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module Rake::Funnel::Extensions
2
+ module CamelCase
3
+ def camelize
4
+ self
5
+ .to_s
6
+ .split('_')
7
+ .inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }
8
+ .join
9
+ end
10
+ end
11
+ end
12
+
13
+ class String
14
+ include Rake::Funnel::Extensions::CamelCase
15
+ end
16
+
17
+ class Symbol
18
+ include Rake::Funnel::Extensions::CamelCase
19
+ end
@@ -0,0 +1,52 @@
1
+ require 'abbrev'
2
+ require 'pathname'
3
+
4
+ module Rake::Funnel::Extensions
5
+ module CommonPath
6
+ def common_path
7
+ list = self
8
+ .to_a
9
+ .compact
10
+ .map { |x| components(x) }
11
+
12
+ min = list.min_by { |x| x.length }
13
+
14
+ matches = list.map do |path|
15
+ longest_prefix = []
16
+
17
+ path.zip(min).each do |left, right|
18
+ if left != right
19
+ next
20
+ end
21
+ longest_prefix << right
22
+ end
23
+
24
+ File.join(longest_prefix)
25
+ end
26
+
27
+ matches.min_by { |x| x.length } || ''
28
+ end
29
+
30
+ private
31
+ def components(path)
32
+ paths = []
33
+ Pathname.new(path).descend do |p|
34
+ paths << p
35
+ end
36
+
37
+ paths.inject([]) { |components, path|
38
+ relative = path.relative_path_from(components.last[:absolute]) if components.any?
39
+
40
+ components << { absolute: path, relative: relative || path }
41
+ }.map { |component| component[:relative].to_s }
42
+ end
43
+ end
44
+ end
45
+
46
+ class Array
47
+ include Rake::Funnel::Extensions::CommonPath
48
+ end
49
+
50
+ class Rake::FileList
51
+ include Rake::Funnel::Extensions::CommonPath
52
+ end
@@ -0,0 +1,27 @@
1
+ require 'smart_colored'
2
+ require 'smart_colored/extend'
3
+
4
+ module Rake::Funnel::Extensions
5
+ module DisableColors
6
+ def self.included(klass)
7
+ original_apply_format = klass.instance_method(:apply_format)
8
+
9
+ define_method(:apply_format) do |format|
10
+ return self unless $stdout.tty?
11
+
12
+ bind_to = self
13
+ bind_to = SmartColored::String.new(self) if klass == SmartColored::String
14
+
15
+ original_apply_format.bind(bind_to).call(format)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class SmartColored::String
22
+ include Rake::Funnel::Extensions::DisableColors
23
+ end
24
+
25
+ class String
26
+ include Rake::Funnel::Extensions::DisableColors
27
+ end
@@ -0,0 +1,23 @@
1
+ require 'rexml/document'
2
+
3
+ module Rake::Funnel::Extensions
4
+ module REXML
5
+ module Functions
6
+ def lower_case(string)
7
+ string.first.to_s.downcase
8
+ end
9
+
10
+ def matches(string, test)
11
+ File.fnmatch?(test, string.first.to_s, File::FNM_CASEFOLD)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ module REXML
18
+ module Functions
19
+ class << self
20
+ include Rake::Funnel::Extensions::REXML::Functions
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,56 @@
1
+ require 'rake'
2
+ require 'open3'
3
+ require 'smart_colored/extend'
4
+
5
+ module Rake::Funnel::Extensions
6
+ module Shell
7
+ def shell(*cmd, log_file: nil, error_lines: nil)
8
+ mkdir_p(File.dirname(log_file)) if log_file
9
+
10
+ stdout = -> (msg) { $stdout.puts msg.sub(/\n$/, '').green }
11
+
12
+ error_logged = false
13
+ stderr = -> (msg) {
14
+ error_logged = true
15
+ $stderr.puts msg.sub(/\n$/, '').bold.red
16
+ }
17
+
18
+ log = StringIO.new
19
+
20
+ begin
21
+ cmd = cmd.flatten.reject(&:nil?)
22
+ Rake.rake_output_message(cmd.join(' '))
23
+
24
+ Open3.popen2e(*cmd) do |_, stdout_and_stderr, wait_thread|
25
+ stdout_and_stderr.each do |line|
26
+ out = stdout
27
+ out = stderr if error_lines && line =~ error_lines
28
+ out.call(line)
29
+
30
+ log.write(line)
31
+ File.open(log_file, 'a') { |f| f.write(line) } if log_file
32
+ end
33
+
34
+ success = wait_thread.value.success? && error_logged == false
35
+ result = [cmd.join(' '),
36
+ wait_thread.value.exitstatus,
37
+ log.string]
38
+
39
+ if block_given?
40
+ yield(success, *result)
41
+ return
42
+ end
43
+
44
+ raise Rake::Funnel::ExecutionError.new(*result) unless success
45
+ end
46
+ ensure
47
+ log.close
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ module Rake::DSL
54
+ include Rake::Funnel::Extensions::Shell
55
+ private(*Rake::Funnel::Extensions::Shell.instance_methods(false))
56
+ end
@@ -0,0 +1,15 @@
1
+ module Rake::Funnel::Extensions; end
2
+ module Rake::Funnel::Integration; end
3
+ module Rake::Funnel::Support; end
4
+ module Rake::Funnel::Tasks; end
5
+
6
+ [
7
+ "#{File.dirname(__FILE__)}/*.rb",
8
+ "#{File.dirname(__FILE__)}/extensions/*.rb",
9
+ "#{File.dirname(__FILE__)}/support/*.rb",
10
+ "#{File.dirname(__FILE__)}/*/*.rb",
11
+ ].each do |path|
12
+ Dir.glob(path).sort.each do |p|
13
+ require p
14
+ end
15
+ end
@@ -0,0 +1,70 @@
1
+ require 'rake'
2
+
3
+ module Rake::Funnel::Integration
4
+ class ProgressReport
5
+ attr_accessor :starting, :finished
6
+
7
+ def initialize
8
+ task_starting do |task, args|
9
+ puts "\n[#{task.name}]" unless Rake::Funnel::Integration::TeamCity.running?
10
+ end
11
+
12
+ task_finished { |task, args, error| }
13
+
14
+ yield self if block_given?
15
+
16
+ patch.apply!
17
+ end
18
+
19
+ def disable!
20
+ patch.revert!
21
+ end
22
+
23
+ def task_starting(&block)
24
+ @starting = block
25
+ end
26
+
27
+ def task_finished(&block)
28
+ @finished = block
29
+ end
30
+
31
+ private
32
+ def patch
33
+ @patch ||= create_patch
34
+ end
35
+
36
+ def create_patch
37
+ Rake::Funnel::Support::Patch.new(self) do |p|
38
+ p.setup do |context|
39
+ Rake::Task.class_eval do
40
+ old_execute = instance_method(:execute)
41
+
42
+ define_method(:execute) do |args|
43
+ context.starting.call(self, args)
44
+
45
+ error = nil
46
+ begin
47
+ old_execute.bind(self).call(args)
48
+ rescue => e
49
+ error = e
50
+ ensure
51
+ context.finished.call(self, args, error)
52
+ raise error if error
53
+ end
54
+ end
55
+
56
+ old_execute
57
+ end
58
+ end
59
+
60
+ p.reset do |memo|
61
+ Rake::Task.class_eval do
62
+ define_method(:execute) do |args|
63
+ memo.bind(self).call(args)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,8 @@
1
+ module Rake::Funnel::Integration
2
+ class SyncOutput
3
+ def initialize
4
+ $stdout.sync = true
5
+ $stderr.sync = true
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,59 @@
1
+ module Rake::Funnel::Integration::TeamCity
2
+ class NUnitPlugin
3
+ ENV_VAR = 'teamcity.dotnet.nunitaddin'
4
+
5
+ class << self
6
+ def setup(nunit_executable)
7
+ addins = get_addin_dir(ENV[ENV_VAR]) || return
8
+ nunit, version = read_version(nunit_executable) || return
9
+
10
+ addin_files = find_teamcity_addins(addins, version) || return
11
+
12
+ copy_addin_files(nunit, addin_files, version)
13
+ end
14
+
15
+ private
16
+ def get_addin_dir(source)
17
+ return nil unless source
18
+
19
+ File.expand_path(source)
20
+ end
21
+
22
+ def read_version(executable)
23
+ nunit = Rake::Funnel::Support::Which.which(executable) || return
24
+ binary = File.read(nunit)
25
+
26
+ version = binary.match(/F\0i\0l\0e\0V\0e\0r\0s\0i\0o\0n\0*(.*?)\0\0\0/)
27
+ if version.nil?
28
+ Rake.rake_output_message("Could read version from NUnit executable in #{nunit}")
29
+ return
30
+ end
31
+
32
+ [
33
+ nunit,
34
+ version[1].gsub(/\0/, '').split('.').take(3).join('.')
35
+ ]
36
+ end
37
+
38
+ def find_teamcity_addins(addins, version)
39
+ addin_files = Dir.glob("#{addins}-#{version}.*")
40
+
41
+ if addin_files.none?
42
+ Rake.rake_output_message("Could not find TeamCity NUnit addin for version #{version} in #{addins}")
43
+ return
44
+ end
45
+
46
+ addin_files
47
+ end
48
+
49
+ def copy_addin_files(nunit, addin_files, version)
50
+ Rake.rake_output_message("Installing TeamCity NUnit addin for version #{version} in #{nunit}")
51
+
52
+ destination = File.join(File.dirname(nunit), 'addins')
53
+
54
+ RakeFileUtils.mkdir_p(destination)
55
+ RakeFileUtils.cp(addin_files, destination)
56
+ end
57
+ end
58
+ end
59
+ end