albacore 1.0.0 → 2.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -21
- data/.travis.yml +31 -12
- data/Gemfile +14 -6
- data/Guardfile +1 -3
- data/README.md +200 -47
- data/Rakefile +9 -19
- data/albacore.gemspec +33 -23
- data/lib/albacore.rb +3 -47
- data/lib/albacore/albacore_module.rb +57 -0
- data/lib/albacore/application.rb +43 -0
- data/lib/albacore/cmd_config.rb +66 -0
- data/lib/albacore/config_dsl.rb +55 -0
- data/lib/albacore/cross_platform_cmd.rb +291 -0
- data/lib/albacore/dsl.rb +90 -0
- data/lib/albacore/errors/command_failed_error.rb +11 -0
- data/lib/albacore/errors/command_not_found_error.rb +13 -0
- data/lib/albacore/errors/unfilled_property_error.rb +14 -0
- data/lib/albacore/ext/README.md +12 -0
- data/lib/albacore/ext/teamcity.rb +64 -0
- data/lib/albacore/facts.rb +25 -0
- data/lib/albacore/logging.rb +32 -0
- data/lib/albacore/nuget_model.rb +387 -0
- data/lib/albacore/paths.rb +34 -0
- data/lib/albacore/project.rb +141 -0
- data/lib/albacore/semver.rb +5 -0
- data/lib/albacore/task_types/asmver.rb +72 -0
- data/lib/albacore/task_types/asmver/cpp.rb +20 -0
- data/lib/albacore/task_types/asmver/cs.rb +17 -0
- data/lib/albacore/task_types/asmver/engine.rb +126 -0
- data/lib/albacore/task_types/asmver/file_generator.rb +45 -0
- data/lib/albacore/task_types/asmver/fs.rb +37 -0
- data/lib/albacore/task_types/asmver/vb.rb +27 -0
- data/lib/albacore/task_types/build.rb +192 -0
- data/lib/albacore/task_types/nugets_authentication.rb +9 -0
- data/lib/albacore/task_types/nugets_pack.rb +378 -0
- data/lib/albacore/task_types/nugets_restore.rb +138 -0
- data/lib/albacore/task_types/test_runner.rb +39 -0
- data/lib/albacore/tasks/README.md +16 -0
- data/lib/albacore/tasks/albasemver.rb +49 -0
- data/lib/albacore/tasks/projectlint.rb +81 -0
- data/lib/albacore/tasks/versionizer.rb +65 -0
- data/lib/albacore/tools/fluent_migrator.rb +177 -0
- data/lib/albacore/tools/restore_hint_paths.rb +112 -0
- data/lib/albacore/version.rb +3 -3
- data/spec/Rakefile +5 -0
- data/spec/albacore_spec.rb +12 -0
- data/spec/asmver_spec.rb +151 -0
- data/spec/asmver_task_spec.rb +32 -0
- data/spec/build_spec.rb +60 -0
- data/spec/config_dsl_spec.rb +83 -0
- data/spec/cross_platform_cmd_spec.rb +65 -0
- data/spec/dsl_spec.rb +39 -0
- data/spec/ext_teamcity_spec.rb +71 -0
- data/spec/facts_spec.rb +7 -0
- data/spec/nuget_model_spec.rb +401 -0
- data/spec/nugets_pack_spec.rb +231 -0
- data/spec/nugets_restore_spec.rb +55 -0
- data/spec/project_spec.rb +26 -0
- data/spec/projectlint/added_but_not_on_filesystem/aproject.csproj +29 -0
- data/spec/projectlint/correct/File.cs +1 -0
- data/spec/projectlint/correct/Image.txt +1 -0
- data/spec/projectlint/correct/MyHeavy.heavy +1 -0
- data/spec/projectlint/correct/Schema.xsd +1 -0
- data/spec/projectlint/correct/SubFolder/AnotherFile.cs +1 -0
- data/spec/projectlint/correct/aproject.csproj +29 -0
- data/spec/projectlint/on_filesystem_but_not_added/File.cs +1 -0
- data/spec/projectlint/on_filesystem_but_not_added/Image.txt +1 -0
- data/spec/projectlint/on_filesystem_but_not_added/aproject.csproj +11 -0
- data/spec/projectlint_spec.rb +77 -0
- data/spec/smoke_spec.rb +55 -0
- data/spec/spec_helper.rb +19 -20
- data/spec/support/Nuget/NuGet.exe +0 -0
- data/spec/support/echo/FSharp.Core.dll +0 -0
- data/spec/support/echo/FSharp.Core.xml +10517 -0
- data/spec/support/echo/echo.XML +12 -0
- data/spec/support/echo/echo.exe +0 -0
- data/spec/support/echo/echo.exe.config +17 -0
- data/spec/support/echo/echo.pdb +0 -0
- data/spec/support/returnstatus/FSharp.Core.dll +0 -0
- data/spec/support/returnstatus/FSharp.Core.xml +10517 -0
- data/spec/support/returnstatus/returnstatus.XML +12 -0
- data/spec/support/returnstatus/returnstatus.exe +0 -0
- data/spec/support/returnstatus/returnstatus.exe.config +17 -0
- data/spec/support/returnstatus/returnstatus.pdb +0 -0
- data/spec/support/sh_interceptor.rb +83 -0
- data/spec/testdata/.gitignore +5 -0
- data/spec/testdata/DebugProject/.gitignore +1 -0
- data/spec/testdata/DebugProject/Degbu.fsproj +57 -0
- data/spec/testdata/DebugProject/Degbu.sln +20 -0
- data/spec/testdata/DebugProject/Gemfile +1 -0
- data/spec/testdata/DebugProject/Library1.fs +4 -0
- data/spec/testdata/DebugProject/Rakefile +22 -0
- data/spec/testdata/EmptyProject/EmptyProject.csproj +39 -0
- data/spec/{assemblyinfo → testdata/EmptyProject/Properties}/AssemblyInfo.cs +5 -5
- data/spec/testdata/Gemfile +1 -0
- data/spec/testdata/NuGet.exe +0 -0
- data/spec/testdata/Project/Library1.fs +4 -0
- data/spec/testdata/Project/Project.fsproj +52 -0
- data/spec/testdata/Project/Project.sln +20 -0
- data/spec/testdata/Project/packages.config +6 -0
- data/spec/testdata/Rakefile +22 -0
- data/spec/testdata/TestingDependencies/Sample.Commands/Library.fs +6 -0
- data/spec/testdata/TestingDependencies/Sample.Commands/Sample.Commands.fsproj +78 -0
- data/spec/testdata/TestingDependencies/Sample.Commands/Script.fsx +8 -0
- data/spec/testdata/TestingDependencies/Sample.Commands/packages.config +6 -0
- data/spec/testdata/TestingDependencies/Sample.Core/Library.fs +3 -0
- data/spec/testdata/TestingDependencies/Sample.Core/Sample.Core.fsproj +59 -0
- data/spec/testdata/TestingDependencies/Sample.Core/Script.fsx +8 -0
- data/spec/testdata/TestingDependencies/Sample.Core/packages.config +4 -0
- data/spec/testdata/TestingDependencies/Sample.sln +26 -0
- data/spec/testdata/TestingDependencies/vendor/FSharp.Core.dll +0 -0
- data/spec/testdata/TestingDependencies/vendor/FSharp.Core.optdata +0 -0
- data/spec/testdata/TestingDependencies/vendor/FSharp.Core.sigdata +0 -0
- data/spec/testdata/TestingDependencies/vendor/FSharp.Core.xml +8748 -0
- data/spec/testdata/example.nuspec +14 -0
- data/spec/testdata/example.symbols.nuspec +21 -0
- data/spec/tools/fluent_migrator_spec.rb +80 -0
- metadata +303 -212
- data/.bundle/config +0 -2
- data/.rspec +0 -2
- data/CONTRIBUTING.md +0 -87
- data/LICENSE +0 -21
- data/lib/albacore/albacoretask.rb +0 -50
- data/lib/albacore/aspnetcompiler.rb +0 -80
- data/lib/albacore/assemblyinfo.rb +0 -163
- data/lib/albacore/assemblyinfolanguages/assemblyinfoengine.rb +0 -54
- data/lib/albacore/assemblyinfolanguages/cppcliengine.rb +0 -18
- data/lib/albacore/assemblyinfolanguages/csharpengine.rb +0 -15
- data/lib/albacore/assemblyinfolanguages/fsharpengine.rb +0 -23
- data/lib/albacore/assemblyinfolanguages/vbnetengine.rb +0 -15
- data/lib/albacore/config/aspnetcompilerconfig.rb +0 -30
- data/lib/albacore/config/assemblyinfoconfig.rb +0 -18
- data/lib/albacore/config/config.rb +0 -22
- data/lib/albacore/config/cscconfig.rb +0 -28
- data/lib/albacore/config/docuconfig.rb +0 -19
- data/lib/albacore/config/execconfig.rb +0 -19
- data/lib/albacore/config/fluentmigratorconfig.rb +0 -19
- data/lib/albacore/config/ilmergeconfig.rb +0 -19
- data/lib/albacore/config/msbuildconfig.rb +0 -29
- data/lib/albacore/config/mspecconfig.rb +0 -19
- data/lib/albacore/config/mstestconfig.rb +0 -19
- data/lib/albacore/config/nantconfig.rb +0 -18
- data/lib/albacore/config/nchurnconfig.rb +0 -19
- data/lib/albacore/config/ncoverconsoleconfig.rb +0 -19
- data/lib/albacore/config/ncoverreportconfig.rb +0 -18
- data/lib/albacore/config/ndependconfig.rb +0 -19
- data/lib/albacore/config/netversion.rb +0 -28
- data/lib/albacore/config/nugetinstallconfig.rb +0 -18
- data/lib/albacore/config/nugetpackconfig.rb +0 -18
- data/lib/albacore/config/nugetpushconfig.rb +0 -18
- data/lib/albacore/config/nugetupdateconfig.rb +0 -18
- data/lib/albacore/config/nunitconfig.rb +0 -19
- data/lib/albacore/config/nuspecconfig.rb +0 -18
- data/lib/albacore/config/plinkconfig.rb +0 -18
- data/lib/albacore/config/specflowconfig.rb +0 -18
- data/lib/albacore/config/sqlcmdconfig.rb +0 -18
- data/lib/albacore/config/unzipconfig.rb +0 -19
- data/lib/albacore/config/xbuildconfig.rb +0 -18
- data/lib/albacore/config/xunitconfig.rb +0 -18
- data/lib/albacore/config/zipdirectoryconfig.rb +0 -18
- data/lib/albacore/csc.rb +0 -77
- data/lib/albacore/docu.rb +0 -38
- data/lib/albacore/exec.rb +0 -20
- data/lib/albacore/fluentmigrator.rb +0 -69
- data/lib/albacore/ilmerge.rb +0 -38
- data/lib/albacore/msbuild.rb +0 -55
- data/lib/albacore/mspec.rb +0 -39
- data/lib/albacore/mstest.rb +0 -47
- data/lib/albacore/nant.rb +0 -41
- data/lib/albacore/nchurn.rb +0 -49
- data/lib/albacore/ncoverconsole.rb +0 -56
- data/lib/albacore/ncoverreport.rb +0 -40
- data/lib/albacore/ncoverreports.rb +0 -16
- data/lib/albacore/ncoverreports/assemblyfilter.rb +0 -10
- data/lib/albacore/ncoverreports/branchcoverage.rb +0 -10
- data/lib/albacore/ncoverreports/classfilter.rb +0 -9
- data/lib/albacore/ncoverreports/codecoveragebase.rb +0 -27
- data/lib/albacore/ncoverreports/cyclomaticcomplexity.rb +0 -23
- data/lib/albacore/ncoverreports/documentfilter.rb +0 -9
- data/lib/albacore/ncoverreports/fullcoveragereport.rb +0 -9
- data/lib/albacore/ncoverreports/methodcoverage.rb +0 -10
- data/lib/albacore/ncoverreports/methodfilter.rb +0 -9
- data/lib/albacore/ncoverreports/namespacefilter.rb +0 -9
- data/lib/albacore/ncoverreports/reportbase.rb +0 -23
- data/lib/albacore/ncoverreports/reportfilterbase.rb +0 -29
- data/lib/albacore/ncoverreports/summaryreport.rb +0 -9
- data/lib/albacore/ncoverreports/symbolcoverage.rb +0 -9
- data/lib/albacore/ndepend.rb +0 -33
- data/lib/albacore/nugetinstall.rb +0 -62
- data/lib/albacore/nugetpack.rb +0 -50
- data/lib/albacore/nugetpush.rb +0 -40
- data/lib/albacore/nugetupdate.rb +0 -50
- data/lib/albacore/nunit.rb +0 -46
- data/lib/albacore/nuspec.rb +0 -180
- data/lib/albacore/output.rb +0 -105
- data/lib/albacore/plink.rb +0 -50
- data/lib/albacore/specflow.rb +0 -30
- data/lib/albacore/sqlcmd.rb +0 -67
- data/lib/albacore/support/attrmethods.rb +0 -33
- data/lib/albacore/support/createtask.rb +0 -50
- data/lib/albacore/support/failure.rb +0 -15
- data/lib/albacore/support/logging.rb +0 -38
- data/lib/albacore/support/openstruct.rb +0 -13
- data/lib/albacore/support/platform.rb +0 -25
- data/lib/albacore/support/runcommand.rb +0 -45
- data/lib/albacore/support/updateattributes.rb +0 -13
- data/lib/albacore/support/yamlconfig.rb +0 -18
- data/lib/albacore/unzip.rb +0 -42
- data/lib/albacore/xbuild.rb +0 -41
- data/lib/albacore/xunit.rb +0 -44
- data/lib/albacore/zipdirectory.rb +0 -106
- data/spec/albacoremodel_spec.rb +0 -52
- data/spec/aspnetcompiler_spec.rb +0 -84
- data/spec/assemblyinfo_spec.rb +0 -209
- data/spec/attrmethods_spec.rb +0 -135
- data/spec/config_spec.rb +0 -32
- data/spec/createtask_spec.rb +0 -234
- data/spec/csc_spec.rb +0 -86
- data/spec/docu_spec.rb +0 -31
- data/spec/exec_spec.rb +0 -25
- data/spec/fluentmigrator_spec.rb +0 -88
- data/spec/ilmerge_spec.rb +0 -35
- data/spec/msbuild_spec.rb +0 -55
- data/spec/mspec_spec.rb +0 -30
- data/spec/mstest_spec.rb +0 -35
- data/spec/nant_spec.rb +0 -40
- data/spec/nchurn_spec.rb +0 -80
- data/spec/ncoverconsole_spec.rb +0 -80
- data/spec/ncoverreport_spec.rb +0 -139
- data/spec/ndepend_spec.rb +0 -26
- data/spec/netversion_spec.rb +0 -51
- data/spec/nugetinstall_spec.rb +0 -59
- data/spec/nugetpack_spec.rb +0 -49
- data/spec/nugetpush_spec.rb +0 -39
- data/spec/nugetupdate_spec.rb +0 -49
- data/spec/nunit_spec.rb +0 -35
- data/spec/nuspec/nuspec.xsd +0 -84
- data/spec/nuspec_spec.rb +0 -74
- data/spec/output/bar/bar.txt +0 -0
- data/spec/output/baz.txt +0 -0
- data/spec/output/erb.txt +0 -1
- data/spec/output/foo/foo/foo.txt +0 -0
- data/spec/output_spec.rb +0 -85
- data/spec/patch/system_patch.rb +0 -12
- data/spec/platform_spec.rb +0 -15
- data/spec/plink_spec.rb +0 -56
- data/spec/runcommand_spec.rb +0 -92
- data/spec/specflow_spec.rb +0 -30
- data/spec/sqlcmd_spec.rb +0 -66
- data/spec/unzip_spec.rb +0 -56
- data/spec/xbuild_spec.rb +0 -40
- data/spec/xunit_spec.rb +0 -30
- data/spec/yaml/test.yml +0 -3
- data/spec/yamlconfig_spec.rb +0 -53
- data/spec/zip/baz.txt +0 -0
- data/spec/zip/foo/bar/bar.txt +0 -0
- data/spec/zip/foo/foo.txt +0 -0
- data/spec/zip_spec.rb +0 -97
data/lib/albacore.rb
CHANGED
@@ -1,47 +1,3 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
require "albacore/config/config"
|
6
|
-
require "albacore/config/netversion"
|
7
|
-
|
8
|
-
require "albacore/support/attrmethods"
|
9
|
-
require "albacore/support/createtask"
|
10
|
-
require "albacore/support/failure"
|
11
|
-
require "albacore/support/logging"
|
12
|
-
require "albacore/support/openstruct"
|
13
|
-
require "albacore/support/runcommand"
|
14
|
-
require "albacore/support/platform"
|
15
|
-
require "albacore/support/updateattributes"
|
16
|
-
require "albacore/support/yamlconfig"
|
17
|
-
|
18
|
-
# tasks
|
19
|
-
require "albacore/aspnetcompiler"
|
20
|
-
require "albacore/assemblyinfo"
|
21
|
-
require "albacore/csc"
|
22
|
-
require "albacore/docu"
|
23
|
-
require "albacore/exec"
|
24
|
-
require "albacore/fluentmigrator"
|
25
|
-
require "albacore/ilmerge"
|
26
|
-
require "albacore/msbuild"
|
27
|
-
require "albacore/mspec"
|
28
|
-
require "albacore/mstest"
|
29
|
-
require "albacore/nant"
|
30
|
-
require "albacore/nchurn"
|
31
|
-
require "albacore/ncoverconsole"
|
32
|
-
require "albacore/ncoverreport"
|
33
|
-
require "albacore/ndepend"
|
34
|
-
require "albacore/nugetinstall"
|
35
|
-
require "albacore/nugetpack"
|
36
|
-
require "albacore/nugetpush"
|
37
|
-
require "albacore/nugetupdate"
|
38
|
-
require "albacore/nunit"
|
39
|
-
require "albacore/nuspec"
|
40
|
-
require "albacore/output"
|
41
|
-
require "albacore/plink"
|
42
|
-
require "albacore/specflow"
|
43
|
-
require "albacore/sqlcmd"
|
44
|
-
require "albacore/unzip"
|
45
|
-
require "albacore/xbuild"
|
46
|
-
require "albacore/xunit"
|
47
|
-
require "albacore/zipdirectory"
|
1
|
+
require 'albacore/version'
|
2
|
+
require 'albacore/albacore_module'
|
3
|
+
require 'albacore/dsl'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'albacore/application'
|
2
|
+
require 'albacore/logging'
|
3
|
+
|
4
|
+
# The albacore module instance methods.
|
5
|
+
module Albacore
|
6
|
+
class << self
|
7
|
+
# Accessor for the Albacore application. Configuration
|
8
|
+
# and similar singleton values will be stored in this
|
9
|
+
# instance. Multiple calls will yield the same instance.
|
10
|
+
def application
|
11
|
+
@application ||= Albacore::Application.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# set the application -- good for testing
|
15
|
+
# the infrastructure of albacore by resetting the
|
16
|
+
# state after each test
|
17
|
+
def set_application app
|
18
|
+
@application = app
|
19
|
+
end
|
20
|
+
|
21
|
+
# Defines a new task with all of what that entails:
|
22
|
+
# will call application.define_task.
|
23
|
+
def define_task *args, &block
|
24
|
+
args = [caller[0][/`.*'/][1..-2]] if args.nil? or args.empty?
|
25
|
+
# delegate to the application singleton
|
26
|
+
application.define_task *args, &block
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set the global albacore logging level.
|
30
|
+
def log_level= level
|
31
|
+
application.logger.level = level
|
32
|
+
end
|
33
|
+
|
34
|
+
# Use to write to STDOUT (by default)
|
35
|
+
def puts *args
|
36
|
+
application.puts *args
|
37
|
+
end
|
38
|
+
|
39
|
+
def events
|
40
|
+
@events ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def subscribe event, &block
|
44
|
+
event = event.to_sym unless event.is_a? Symbol
|
45
|
+
events[event] ||= Set.new
|
46
|
+
events[event].add block
|
47
|
+
end
|
48
|
+
|
49
|
+
def publish event, obj
|
50
|
+
if events.member? event
|
51
|
+
events[event].each { |m| m.call(obj) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Albacore.log_level = Logger::DEBUG if ENV["DEBUG"]
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rake'
|
2
|
+
module Albacore
|
3
|
+
class Application
|
4
|
+
|
5
|
+
# the logger instance for this application
|
6
|
+
attr_reader :logger
|
7
|
+
|
8
|
+
# the output IO for this application, defaults to
|
9
|
+
# STDOUT
|
10
|
+
attr_reader :output
|
11
|
+
|
12
|
+
# the standard IO error output
|
13
|
+
attr_reader :output_err
|
14
|
+
|
15
|
+
# initialize a new albacore application with a given log IO object
|
16
|
+
def initialize log = STDOUT, output = STDOUT, output_err = STDERR
|
17
|
+
raise ArgumentError, "log must not be nil" unless log
|
18
|
+
raise ArgumentError, "output must not be nil" unless output
|
19
|
+
raise ArgumentError, "out_err must not be nil" unless output_err
|
20
|
+
@logger = Logger.new log
|
21
|
+
@logger.level = Logger::INFO
|
22
|
+
@logger.formatter = proc do |severity, datetime, progname, msg|
|
23
|
+
"#{severity[0]} #{datetime.to_datetime.iso8601(6)}: #{msg}\n"
|
24
|
+
end
|
25
|
+
@output = output
|
26
|
+
@output_err = output_err
|
27
|
+
end
|
28
|
+
|
29
|
+
def define_task *args, &block
|
30
|
+
Rake::Task.define_task *args, &block
|
31
|
+
end
|
32
|
+
|
33
|
+
# wite a line to stdout
|
34
|
+
def puts *args
|
35
|
+
@output.puts *args
|
36
|
+
end
|
37
|
+
|
38
|
+
# write a line to stderr
|
39
|
+
def err *args
|
40
|
+
@output_err.puts *args
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require 'albacore/config_dsl'
|
5
|
+
|
6
|
+
module Albacore
|
7
|
+
|
8
|
+
# Use on **configuration** objects that are command-oriented.
|
9
|
+
#
|
10
|
+
# a mixin that adds a couple of field writers and readers.
|
11
|
+
# specifically, allows the configuration to have a work_dir and exe field
|
12
|
+
# and defined a method that joins paths relative to the work_dir
|
13
|
+
module CmdConfig
|
14
|
+
include Logging
|
15
|
+
self.extend ConfigDSL
|
16
|
+
|
17
|
+
# TODO: move towards opts for all task types rather than
|
18
|
+
# reading these public properties.
|
19
|
+
|
20
|
+
# the working directory for this command
|
21
|
+
attr_path_accessor :work_dir
|
22
|
+
|
23
|
+
# TODO: move towards opts for all task types rather than
|
24
|
+
# reading these public properties.
|
25
|
+
|
26
|
+
# field field denoting the path of the executable that should be on the path
|
27
|
+
# specified in the work_dir parameter.
|
28
|
+
attr_path_accessor :exe
|
29
|
+
|
30
|
+
# TODO: move towards opts for all task types rather than
|
31
|
+
# reading these public properties.
|
32
|
+
|
33
|
+
# returns a Set with parameters
|
34
|
+
def parameters
|
35
|
+
@parameters ||= Set.new
|
36
|
+
end
|
37
|
+
|
38
|
+
# add a parameter to the list of parameters to pass to the executable
|
39
|
+
def add_parameter param
|
40
|
+
parameters.add param
|
41
|
+
end
|
42
|
+
|
43
|
+
# helper method that joins the path segments with
|
44
|
+
# respect to the work_dir.
|
45
|
+
private
|
46
|
+
def join *segments
|
47
|
+
segments ||= []
|
48
|
+
segments.unshift work_dir
|
49
|
+
File.join segments
|
50
|
+
end
|
51
|
+
|
52
|
+
# helper method that changes directory to the work directory
|
53
|
+
# and then yields to the block
|
54
|
+
def in_work_dir
|
55
|
+
unless @work_dir.nil?
|
56
|
+
Dir.chdir @work_dir do
|
57
|
+
trace "in work dir '#{@work_dir}'"
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
else
|
61
|
+
trace "not in work dir, because it is nil."
|
62
|
+
yield
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'albacore/paths'
|
2
|
+
|
3
|
+
module Albacore
|
4
|
+
# a small DSL to mix into your configuration classes
|
5
|
+
module ConfigDSL
|
6
|
+
# creates a new attr_writer for the symbols passed,
|
7
|
+
# such that a write to that method will normalise the paths
|
8
|
+
# of the written value: you can pass an optional callback
|
9
|
+
def attr_path *syms, &block
|
10
|
+
given = block_given?
|
11
|
+
|
12
|
+
syms.each do |sym|
|
13
|
+
|
14
|
+
# this is the callback method when the value is set
|
15
|
+
self.send(:define_method, :"__on_#{sym}") do |val|
|
16
|
+
instance_exec(val, &block) if given
|
17
|
+
end
|
18
|
+
|
19
|
+
# this is the setter, it also calls the callback method
|
20
|
+
# defined above.
|
21
|
+
self.class_eval(
|
22
|
+
%{def #{sym}= val
|
23
|
+
@#{sym} = ::Albacore::Paths.normalise_slashes val
|
24
|
+
__on_#{sym} @#{sym}
|
25
|
+
end})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# read/write attribute with rewriting of set values to
|
30
|
+
# match the system's paths
|
31
|
+
def attr_path_accessor *syms, &block
|
32
|
+
given = block_given?
|
33
|
+
|
34
|
+
syms.each do |sym|
|
35
|
+
|
36
|
+
# this is the callback method when the value is set
|
37
|
+
self.send(:define_method, :"__on_#{sym}") do |val|
|
38
|
+
instance_exec(val, &block) if given
|
39
|
+
end
|
40
|
+
|
41
|
+
# this is the setter and getter. The setter also calls
|
42
|
+
# the callback method defined above.
|
43
|
+
self.class_eval(
|
44
|
+
%{def #{sym}= val
|
45
|
+
@#{sym} = ::Albacore::Paths.normalise_slashes val
|
46
|
+
__on_#{sym} @#{sym}
|
47
|
+
end})
|
48
|
+
self.class_eval(
|
49
|
+
%{def #{sym}
|
50
|
+
@#{sym}
|
51
|
+
end})
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'map'
|
3
|
+
require 'open3'
|
4
|
+
require 'timeout'
|
5
|
+
require 'processpilot/processpilot'
|
6
|
+
require 'albacore/paths'
|
7
|
+
require 'albacore/logging'
|
8
|
+
require 'albacore/errors/command_not_found_error'
|
9
|
+
require 'albacore/errors/command_failed_error'
|
10
|
+
|
11
|
+
module Albacore
|
12
|
+
# module for normalising slashes across operating systems
|
13
|
+
# and running commands
|
14
|
+
module CrossPlatformCmd
|
15
|
+
include Logging
|
16
|
+
|
17
|
+
# Exit status class for times the system just gives us a nil.
|
18
|
+
class PseudoStatus
|
19
|
+
attr_reader :exitstatus
|
20
|
+
def initialize(code=0)
|
21
|
+
@exitstatus = code
|
22
|
+
end
|
23
|
+
def to_i
|
24
|
+
@exitstatus << 8
|
25
|
+
end
|
26
|
+
def >>(n)
|
27
|
+
to_i >> n
|
28
|
+
end
|
29
|
+
def stopped?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
def exited?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
include CrossPlatformCmd
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :pid
|
42
|
+
|
43
|
+
KILL_TIMEOUT = 2 # seconds
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
pid = Process.pid
|
47
|
+
at_exit { stop if Process.pid == pid }
|
48
|
+
end
|
49
|
+
|
50
|
+
# run executable
|
51
|
+
#
|
52
|
+
# system(cmd, [args array], Hash(opts), block|ok,status|)
|
53
|
+
# ok => false if bad exit code, or the output otherwise
|
54
|
+
#
|
55
|
+
# options are passed as the last argument
|
56
|
+
#
|
57
|
+
# options:
|
58
|
+
# work_dir: a file path (default '.')
|
59
|
+
# silent: whether to supress all output or not (default false)
|
60
|
+
# output: whether to supress the command's output (default false)
|
61
|
+
# out: output pipe
|
62
|
+
# err: error pipe
|
63
|
+
#
|
64
|
+
def system *cmd, &block
|
65
|
+
raise ArgumentError, "cmd is nil" if cmd.nil? # don't allow nothing to be passed
|
66
|
+
opts = Map.options((Hash === cmd.last) ? cmd.pop : {}). # same arg parsing as rake
|
67
|
+
apply(
|
68
|
+
silent: false,
|
69
|
+
output: true,
|
70
|
+
work_dir: FileUtils.pwd,
|
71
|
+
out: Albacore.application.output,
|
72
|
+
err: Albacore.application.output_err)
|
73
|
+
|
74
|
+
exe, pars, printable, block = prepare_command cmd, &block
|
75
|
+
|
76
|
+
# TODO: figure out how to interleave output and error streams
|
77
|
+
out, _, inmem = opts.get(:out), opts.get(:err), StringIO.new
|
78
|
+
|
79
|
+
trace { "system( exe=#{exe}, pars=[#{pars.join(', ')}], options=#{opts.to_s}), in directory: #{opts.getopt(:workdir, '<<current>>')} [cross_platform_cmd #system]" }
|
80
|
+
|
81
|
+
puts printable unless opts.get :silent, false # log cmd verbatim
|
82
|
+
|
83
|
+
handle_not_found block do
|
84
|
+
# create a pipe for the process to work with
|
85
|
+
read, write = IO.pipe
|
86
|
+
eread, ewrite = IO.pipe
|
87
|
+
|
88
|
+
# this thread chews through the output
|
89
|
+
@out_thread = Thread.new {
|
90
|
+
while !read.eof?
|
91
|
+
data = read.readpartial(1024)
|
92
|
+
out.write data
|
93
|
+
inmem.write data # to give the block at the end
|
94
|
+
end
|
95
|
+
}
|
96
|
+
|
97
|
+
debug 'execute the new process, letting it write to the write FD (file descriptor)'
|
98
|
+
@pid = Process.spawn(*[exe, *pars],
|
99
|
+
out: write,
|
100
|
+
# err: ewrite,
|
101
|
+
chdir: opts.get(:work_dir))
|
102
|
+
|
103
|
+
debug 'waiting for process completion'
|
104
|
+
_, status = Process.wait2 @pid
|
105
|
+
|
106
|
+
#debug 'waiting for thread completion'
|
107
|
+
#@out_thread.join
|
108
|
+
|
109
|
+
return block.call(status.success? && inmem.string, status)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def stop
|
114
|
+
if pid
|
115
|
+
begin
|
116
|
+
Process.kill('TERM', pid)
|
117
|
+
|
118
|
+
begin
|
119
|
+
Timeout.timeout(KILL_TIMEOUT) { Process.wait(pid) }
|
120
|
+
rescue Timeout::Error
|
121
|
+
Process.kill('KILL', pid)
|
122
|
+
Process.wait(pid)
|
123
|
+
end
|
124
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
125
|
+
# Zed's dead, baby
|
126
|
+
end
|
127
|
+
|
128
|
+
@out_thread.kill
|
129
|
+
@pid = nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# http://www.ruby-doc.org/core-2.0/Process.html#method-c-spawn
|
134
|
+
# https://practicingruby.com/articles/shared/ujxrxprnlugz
|
135
|
+
# https://github.com/jonleighton/poltergeist/blob/3365dadfb6242b0b91fe00359ff881e582cc2557/lib/capybara/poltergeist/client.rb
|
136
|
+
|
137
|
+
# run in shell
|
138
|
+
def sh *cmd, &block
|
139
|
+
raise ArgumentError, "cmd is nil" if cmd.nil? # don't allow nothing to be passed
|
140
|
+
opts = Map.options((Hash === cmd.last) ? cmd.pop : {}) # same arg parsing as rake
|
141
|
+
|
142
|
+
cmd = cmd.join(' ') # shell needs a single string
|
143
|
+
block = handler_with_message cmd unless block_given?
|
144
|
+
|
145
|
+
chdir opts.get(:work_dir) do
|
146
|
+
|
147
|
+
trace { "#sh( ..., options: #{opts.to_s}) [cross_platform_cmd #sh]" }
|
148
|
+
puts cmd unless opts.getopt :silent, false # log cmd verbatim
|
149
|
+
|
150
|
+
lines = ''
|
151
|
+
handle_not_found block do
|
152
|
+
IO.popen(cmd, 'r') do |io|
|
153
|
+
io.each do |line|
|
154
|
+
lines << line
|
155
|
+
puts line if opts.getopt(:output, true) or not opts.getopt(:silent, false)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
return block.call($? == 0 && lines, $?)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# shell ignore exit code
|
165
|
+
# returns:
|
166
|
+
# [ok, status]
|
167
|
+
# where status:
|
168
|
+
# #exitstatus : Int
|
169
|
+
# #pid : Int
|
170
|
+
def shie *cmd, &block
|
171
|
+
block = lambda { |ok, status| ok } unless block_given?
|
172
|
+
sh *cmd, &block
|
173
|
+
end
|
174
|
+
|
175
|
+
def system_control cmd, *opts, &block
|
176
|
+
cmd = opts[0]
|
177
|
+
opts = Map.options((Hash === cmd.last) ? cmd.pop : {}) # same arg parsing as rake
|
178
|
+
chdir opts[:work_dir] do
|
179
|
+
puts cmd
|
180
|
+
ProcessPilot::pilot cmd, opts, &block
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def normalise_slashes path
|
185
|
+
::Albacore::Paths.normalise_slashes path
|
186
|
+
end
|
187
|
+
|
188
|
+
# create a new command string
|
189
|
+
def make_command
|
190
|
+
::Albacore::Paths.make_command @executable, @parameters
|
191
|
+
end
|
192
|
+
|
193
|
+
def which executable
|
194
|
+
raise ArgumentError, "executable is nil" unless executable
|
195
|
+
|
196
|
+
dir = File.dirname executable
|
197
|
+
file = File.basename executable
|
198
|
+
|
199
|
+
cmd = ::Rake::Win32.windows? ? 'where' : 'which'
|
200
|
+
parameters = []
|
201
|
+
parameters << Paths.normalise_slashes(file) if dir == '.'
|
202
|
+
parameters << Paths.normalise_slashes("#{dir}:#{file}") unless dir == '.'
|
203
|
+
cmd, parameters = Paths.normalise cmd, parameters
|
204
|
+
|
205
|
+
trace { "#{cmd} #{parameters.join(' ')} [cross_platform_cmd #which]" }
|
206
|
+
|
207
|
+
null = ::Rake::Win32.windows? ? "NUL" : "/dev/null"
|
208
|
+
res = IO.popen([cmd, *parameters]) do |io|
|
209
|
+
io.read.chomp
|
210
|
+
end
|
211
|
+
|
212
|
+
unless $? == 0
|
213
|
+
nil
|
214
|
+
else
|
215
|
+
res
|
216
|
+
end
|
217
|
+
rescue Errno::ENOENT => e
|
218
|
+
trace "which/where returned #{$?}: #{e} [cross_platform_cmd #which]"
|
219
|
+
nil
|
220
|
+
end
|
221
|
+
|
222
|
+
def chdir wd, &block
|
223
|
+
return block.call if wd.nil?
|
224
|
+
Dir.chdir wd do
|
225
|
+
debug { "pushd #{wd} [cross_platform_cmd #chdir]" }
|
226
|
+
res = block.call
|
227
|
+
debug { "popd #{wd} [cross_platform_cmd #chdir]" }
|
228
|
+
return res
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
private
|
233
|
+
|
234
|
+
def prepare_command cmd, &block
|
235
|
+
pars = cmd[1..-1].flatten
|
236
|
+
raise ArgumentError, "arguments 1..-1 must be an array" unless pars.is_a? Array
|
237
|
+
|
238
|
+
exe, pars = ::Albacore::Paths.normalise cmd[0], pars
|
239
|
+
printable = %Q{#{exe} #{pars.join(' ')}}
|
240
|
+
handler = block_given? ? block : handler_with_message(printable)
|
241
|
+
[exe, pars, printable, handler]
|
242
|
+
end
|
243
|
+
|
244
|
+
def handler_with_message printable
|
245
|
+
lambda { |ok, status| ok or raise_failure(printable, status) }
|
246
|
+
end
|
247
|
+
|
248
|
+
# handles the errors from not finding the executable on the system
|
249
|
+
def handle_not_found rescue_block
|
250
|
+
yield
|
251
|
+
rescue Errno::ENOENT => e
|
252
|
+
rescue_block.call(nil, PseudoStatus.new(127))
|
253
|
+
rescue IOError => e # rescue for JRuby
|
254
|
+
rescue_block.call(nil, PseudoStatus.new(127))
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
def knowns
|
259
|
+
{ 127 => 'number 127 in particular means that the operating system could not find the executable' }
|
260
|
+
end
|
261
|
+
|
262
|
+
def raise_failure cmd, status
|
263
|
+
if status.exitstatus == 127
|
264
|
+
raise CommandNotFoundError.new(format_failure(cmd, status), cmd)
|
265
|
+
else
|
266
|
+
raise CommandFailedError.new(format_failure(cmd, status), cmd)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def format_failure cmd, status
|
271
|
+
if knowns.has_key? status.exitstatus
|
272
|
+
%{Command failed with status (#{status.exitstatus}) - #{knowns[status.exitstatus]}:
|
273
|
+
#{cmd}}
|
274
|
+
else
|
275
|
+
%{Command failed with status (#{status.exitstatus}):
|
276
|
+
#{cmd}}
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# shuffle the executable to be a parameter to
|
281
|
+
# mono, if not on windows.
|
282
|
+
def mono_command
|
283
|
+
unless ::Rake::Win32.windows?
|
284
|
+
trace 'detected running on mono -- unshifting exe file for mono'
|
285
|
+
executable = @executable
|
286
|
+
@executable = "mono"
|
287
|
+
@parameters.unshift executable
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|