toys 0.3.7.1 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +19 -22
- data/builtins/system.rb +1 -1
- data/docs/guide.md +830 -105
- data/lib/toys.rb +5 -0
- data/lib/toys/standard_cli.rb +6 -1
- data/lib/toys/templates/clean.rb +85 -0
- data/lib/toys/templates/gem_build.rb +125 -0
- data/lib/toys/templates/minitest.rb +125 -0
- data/lib/toys/templates/rubocop.rb +86 -0
- data/lib/toys/templates/yardoc.rb +101 -0
- data/lib/toys/version.rb +1 -1
- metadata +9 -4
data/lib/toys.rb
CHANGED
data/lib/toys/standard_cli.rb
CHANGED
@@ -108,7 +108,8 @@ module Toys
|
|
108
108
|
config_file_name: CONFIG_FILE_NAME,
|
109
109
|
index_file_name: INDEX_FILE_NAME,
|
110
110
|
preload_file_name: PRELOAD_FILE_NAME,
|
111
|
-
middleware_stack: default_middleware_stack
|
111
|
+
middleware_stack: default_middleware_stack,
|
112
|
+
template_lookup: default_template_lookup
|
112
113
|
)
|
113
114
|
add_standard_paths(cli, directory: directory)
|
114
115
|
cli
|
@@ -190,5 +191,9 @@ module Toys
|
|
190
191
|
end
|
191
192
|
|
192
193
|
# rubocop:enable Metrics/MethodLength
|
194
|
+
|
195
|
+
def self.default_template_lookup
|
196
|
+
Utils::ModuleLookup.new.add_path("toys/templates")
|
197
|
+
end
|
193
198
|
end
|
194
199
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
module Toys
|
31
|
+
module Templates
|
32
|
+
##
|
33
|
+
# A template for tools that clean build artifacts
|
34
|
+
#
|
35
|
+
class Clean
|
36
|
+
include Template
|
37
|
+
|
38
|
+
##
|
39
|
+
# Default tool name
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
DEFAULT_TOOL_NAME = "clean".freeze
|
43
|
+
|
44
|
+
##
|
45
|
+
# Create the template settings for the Clean template.
|
46
|
+
#
|
47
|
+
# @param [String] name Name of the tool to create. Defaults to
|
48
|
+
# {DEFAULT_TOOL_NAME}.
|
49
|
+
# @param [Array<String>] paths An array of glob patterns indicating what
|
50
|
+
# to clean.
|
51
|
+
#
|
52
|
+
def initialize(name: DEFAULT_TOOL_NAME, paths: [])
|
53
|
+
@name = name
|
54
|
+
@paths = paths
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_accessor :name
|
58
|
+
attr_accessor :paths
|
59
|
+
|
60
|
+
to_expand do |template|
|
61
|
+
tool(template.name) do
|
62
|
+
desc "Clean built files and directories."
|
63
|
+
|
64
|
+
include :fileutils
|
65
|
+
|
66
|
+
run do
|
67
|
+
files = []
|
68
|
+
patterns = Array(template.paths)
|
69
|
+
patterns.each do |pattern|
|
70
|
+
files.concat(::Dir.glob(pattern))
|
71
|
+
end
|
72
|
+
files.uniq!
|
73
|
+
|
74
|
+
files.each do |file|
|
75
|
+
if ::File.exist?(file)
|
76
|
+
rm_rf file
|
77
|
+
puts "Cleaned: #{file}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
require "rubygems/package"
|
31
|
+
|
32
|
+
module Toys
|
33
|
+
module Templates
|
34
|
+
##
|
35
|
+
# A template for tools that build and release gems
|
36
|
+
#
|
37
|
+
class GemBuild
|
38
|
+
include Template
|
39
|
+
|
40
|
+
##
|
41
|
+
# Default tool name
|
42
|
+
# @return [String]
|
43
|
+
#
|
44
|
+
DEFAULT_TOOL_NAME = "build".freeze
|
45
|
+
|
46
|
+
##
|
47
|
+
# Create the template settings for the GemBuild template.
|
48
|
+
#
|
49
|
+
# @param [String] name Name of the tool to create. Defaults to
|
50
|
+
# {DEFAULT_TOOL_NAME}.
|
51
|
+
# @param [String] gem_name Name of the gem to build. If not provided,
|
52
|
+
# defaults to the first gemspec file it finds.
|
53
|
+
# @param [Boolean] push_gem If true, pushes the built gem to rubygems.
|
54
|
+
# @param [Boolean] tag If true, tags the git repo with the gem version.
|
55
|
+
# @param [Boolean,String] push_tag If truthy, pushes the new tag to
|
56
|
+
# a git remote. You may specify which remote by setting the value to
|
57
|
+
# a string. Otherwise, if the value is simply `true`, the "origin"
|
58
|
+
# remote is used by default.
|
59
|
+
#
|
60
|
+
def initialize(name: DEFAULT_TOOL_NAME,
|
61
|
+
gem_name: nil,
|
62
|
+
push_gem: false,
|
63
|
+
tag: false,
|
64
|
+
push_tag: false)
|
65
|
+
@name = name
|
66
|
+
@gem_name = gem_name
|
67
|
+
@push_gem = push_gem
|
68
|
+
@tag = tag
|
69
|
+
@push_tag = push_tag
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_accessor :name
|
73
|
+
attr_accessor :gem_name
|
74
|
+
attr_accessor :push_gem
|
75
|
+
attr_accessor :tag
|
76
|
+
attr_accessor :push_tag
|
77
|
+
|
78
|
+
to_expand do |template|
|
79
|
+
unless template.gem_name
|
80
|
+
candidates = ::Dir.glob("*.gemspec")
|
81
|
+
if candidates.empty?
|
82
|
+
raise ToolDefinitionError, "Could not find a gemspec"
|
83
|
+
end
|
84
|
+
template.gem_name = candidates.first.sub(/\.gemspec$/, "")
|
85
|
+
end
|
86
|
+
task_type = template.push_gem ? "Release" : "Build"
|
87
|
+
|
88
|
+
tool(template.name) do
|
89
|
+
desc "#{task_type} the gem: #{template.gem_name}"
|
90
|
+
|
91
|
+
flag :yes, "-y", "--yes", desc: "Do not ask for interactive confirmation"
|
92
|
+
|
93
|
+
include :exec
|
94
|
+
include :fileutils
|
95
|
+
include :terminal
|
96
|
+
|
97
|
+
run do
|
98
|
+
configure_exec(exit_on_nonzero_status: true)
|
99
|
+
gemspec = ::Gem::Specification.load "#{template.gem_name}.gemspec"
|
100
|
+
version = gemspec.version
|
101
|
+
gemfile = "#{template.gem_name}-#{version}.gem"
|
102
|
+
::Gem::Package.build gemspec
|
103
|
+
mkdir_p "pkg"
|
104
|
+
mv gemfile, "pkg"
|
105
|
+
if template.push_gem
|
106
|
+
if ::File.directory?(".git") && capture("git status -s").strip != ""
|
107
|
+
logger.error "Cannot push the gem when there are uncommited changes"
|
108
|
+
exit(1)
|
109
|
+
end
|
110
|
+
exit(1) unless option(:yes) || confirm("Release #{gemfile}?")
|
111
|
+
sh "gem push pkg/#{gemfile}"
|
112
|
+
if template.tag
|
113
|
+
sh "git tag v#{version}"
|
114
|
+
if template.push_tag
|
115
|
+
template.push_tag = "origin" if template.push_tag == true
|
116
|
+
sh "git push #{template.push_tag} v#{version}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
module Toys
|
31
|
+
module Templates
|
32
|
+
##
|
33
|
+
# A template for tools that run minitest
|
34
|
+
#
|
35
|
+
class Minitest
|
36
|
+
include Template
|
37
|
+
|
38
|
+
##
|
39
|
+
# Default tool name
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
DEFAULT_TOOL_NAME = "test".freeze
|
43
|
+
|
44
|
+
##
|
45
|
+
# Default set of library paths
|
46
|
+
# @return [Array<String>]
|
47
|
+
#
|
48
|
+
DEFAULT_LIBS = ["lib"].freeze
|
49
|
+
|
50
|
+
##
|
51
|
+
# Default set of test file globs
|
52
|
+
# @return [Array<String>]
|
53
|
+
#
|
54
|
+
DEFAULT_FILES = ["test/**/test*.rb"].freeze
|
55
|
+
|
56
|
+
##
|
57
|
+
# Create the template settings for the Minitest template.
|
58
|
+
#
|
59
|
+
# @param [String] name Name of the tool to create. Defaults to
|
60
|
+
# {DEFAULT_TOOL_NAME}.
|
61
|
+
# @param [Array<String>] libs An array of library paths to add to the
|
62
|
+
# ruby require path. Defaults to {DEFAULT_LIBS}.
|
63
|
+
# @param [Array<String>] files An array of globs indicating the test
|
64
|
+
# files to load. Defaults to {DEFAULT_FILES}.
|
65
|
+
# @param [Boolean] warnings If true, runs tests with Ruby warnings.
|
66
|
+
# Defaults to true.
|
67
|
+
#
|
68
|
+
def initialize(name: DEFAULT_TOOL_NAME,
|
69
|
+
libs: DEFAULT_LIBS,
|
70
|
+
files: DEFAULT_FILES,
|
71
|
+
warnings: true)
|
72
|
+
@name = name
|
73
|
+
@libs = libs
|
74
|
+
@files = files
|
75
|
+
@warnings = warnings
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_accessor :name
|
79
|
+
attr_accessor :libs
|
80
|
+
attr_accessor :files
|
81
|
+
attr_accessor :warnings
|
82
|
+
|
83
|
+
to_expand do |template|
|
84
|
+
tool(template.name) do
|
85
|
+
desc "Run minitest on the current project."
|
86
|
+
|
87
|
+
include :exec
|
88
|
+
|
89
|
+
flag :warnings, "-w", "--[no-]warnings",
|
90
|
+
default: template.warnings,
|
91
|
+
desc: "Turn on Ruby warnings (defaults to #{template.warnings})"
|
92
|
+
|
93
|
+
remaining_args :tests, desc: "Paths to the tests to run (defaults to all tests)"
|
94
|
+
|
95
|
+
run do
|
96
|
+
ruby_args = []
|
97
|
+
unless template.libs.empty?
|
98
|
+
lib_path = template.libs.join(::File::PATH_SEPARATOR)
|
99
|
+
ruby_args << "-I#{lib_path}"
|
100
|
+
end
|
101
|
+
ruby_args << "-w" if self[:warnings]
|
102
|
+
|
103
|
+
tests = self[:tests]
|
104
|
+
if tests.empty?
|
105
|
+
Array(template.files).each do |pattern|
|
106
|
+
tests.concat(::Dir.glob(pattern))
|
107
|
+
end
|
108
|
+
tests.uniq!
|
109
|
+
end
|
110
|
+
|
111
|
+
result = ruby(ruby_args, in: :controller) do |controller|
|
112
|
+
tests.each do |file|
|
113
|
+
controller.in.puts("load '#{file}'")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
if result.error?
|
117
|
+
logger.error("Minitest failed!")
|
118
|
+
exit(result.exit_code)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
module Toys
|
31
|
+
module Templates
|
32
|
+
##
|
33
|
+
# A template for tools that run rubocop
|
34
|
+
#
|
35
|
+
class Rubocop
|
36
|
+
include Template
|
37
|
+
|
38
|
+
##
|
39
|
+
# Default tool name
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
DEFAULT_TOOL_NAME = "rubocop".freeze
|
43
|
+
|
44
|
+
##
|
45
|
+
# Create the template settings for the Rubocop template.
|
46
|
+
#
|
47
|
+
# @param [String] name Name of the tool to create. Defaults to
|
48
|
+
# {DEFAULT_TOOL_NAME}.
|
49
|
+
# @param [Boolean] fail_on_error If true, exits with a nonzero code if
|
50
|
+
# Rubocop fails. Defaults to true.
|
51
|
+
# @param [Array<String>] options Additional options passed to the Rubocop
|
52
|
+
# CLI.
|
53
|
+
#
|
54
|
+
def initialize(name: DEFAULT_TOOL_NAME,
|
55
|
+
fail_on_error: true,
|
56
|
+
options: [])
|
57
|
+
@name = name
|
58
|
+
@fail_on_error = fail_on_error
|
59
|
+
@options = options
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_accessor :name
|
63
|
+
attr_accessor :fail_on_error
|
64
|
+
attr_accessor :options
|
65
|
+
|
66
|
+
to_expand do |template|
|
67
|
+
tool(template.name) do
|
68
|
+
desc "Run rubocop on the current project."
|
69
|
+
|
70
|
+
include :exec
|
71
|
+
|
72
|
+
run do
|
73
|
+
require "rubocop"
|
74
|
+
cli = ::RuboCop::CLI.new
|
75
|
+
logger.info "Running RuboCop..."
|
76
|
+
result = cli.run(template.options)
|
77
|
+
if result.nonzero?
|
78
|
+
logger.error "RuboCop failed!"
|
79
|
+
exit(1) if template.fail_on_error
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|