skippy 0.1.0.a
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 +11 -0
- data/.vscode/settings.json +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +61 -0
- data/Rakefile +10 -0
- data/Skippy.sublime-project +25 -0
- data/app/boot.rb +43 -0
- data/app/commands/debug.rb +15 -0
- data/app/commands/new.rb +97 -0
- data/app/commands/template.rb +27 -0
- data/app/resources/commands/example.rb +14 -0
- data/app/templates/standard/%ext_name%.rb.tt +45 -0
- data/app/templates/standard/%ext_name%/main.rb.tt +21 -0
- data/app/templates/webdialog/extension.rb.erb +45 -0
- data/app/templates/webdialog/extension/html/dialog.html +6 -0
- data/app/templates/webdialog/extension/main.rb.erb +24 -0
- data/bin/bundler +17 -0
- data/bin/console +14 -0
- data/bin/rake +17 -0
- data/bin/setup +8 -0
- data/bin/skippy +17 -0
- data/bin/thor +17 -0
- data/exe/skippy +2 -0
- data/lib/skippy.rb +5 -0
- data/lib/skippy/app.rb +62 -0
- data/lib/skippy/cli.rb +191 -0
- data/lib/skippy/command.rb +15 -0
- data/lib/skippy/error.rb +4 -0
- data/lib/skippy/group.rb +17 -0
- data/lib/skippy/namespace.rb +55 -0
- data/lib/skippy/project.rb +90 -0
- data/lib/skippy/skippy.rb +9 -0
- data/lib/skippy/version.rb +3 -0
- data/skippy.gemspec +31 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6005a25ffc1f9757b4cf9656d97be15351463830
|
4
|
+
data.tar.gz: da9d85e6b9c72eeee60b18fed419722e13829a64
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc7071ef383374ae27cc9fa15d15544dac943d07a53832f91712f8f8a44d9c1d7eeb0286babae6a3cfdb3b4d91b074a4693f2ab825d6f700961942d6fd5ec4c4
|
7
|
+
data.tar.gz: 0ce7d0c9935e0f607e1367062a297ccc83788efebea2330f282bd1d6f8608b4a72f5fb158a8f26a5f5b9e893c94ef9727e29c2b15039cc5cf7d835ebb81dd508
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Thomas Thomassen
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Skippy
|
2
|
+
|
3
|
+
Skippy is a Command Line Interface which aims to automate common developer tasks for SketchUp Ruby extension development.
|
4
|
+
|
5
|
+
It is currently in very early stage of development so many things are incomplete. Feedback and contributions are welcome.
|
6
|
+
|
7
|
+
Some of the main goals are:
|
8
|
+
|
9
|
+
* Automate common tasks
|
10
|
+
* Packaging the extension
|
11
|
+
* Running build scripts
|
12
|
+
* Easy interface to add per-project custom commands/tasks
|
13
|
+
* Quick initialization of new project with templates
|
14
|
+
* Library dependency management
|
15
|
+
* Pull in third-party modules into extension namespace
|
16
|
+
* Add/Remove/Update dependencies
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
$ gem install skippy
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
TODO: Write more detailed usage instructions here.
|
25
|
+
|
26
|
+
Install the gem on your system, afterwards the `skippy` command should become available.
|
27
|
+
|
28
|
+
### Quick-Reference
|
29
|
+
|
30
|
+
Type `skippy` to list available commands.
|
31
|
+
|
32
|
+
Type `skippy help [COMMAND]` for more information on how to use each command.
|
33
|
+
|
34
|
+
Use `skippy new` to create a new project in the current folder.
|
35
|
+
|
36
|
+
You can add custom per-project commands to a `skippy` folder in your project. Look at `skippy/example.rb` for an example of a simple custom command.
|
37
|
+
|
38
|
+
### Power of Thor
|
39
|
+
|
40
|
+
Skippy is built on [Thor](https://github.com/erikhuda/thor). Refer to [Thor's Website](http://whatisthor.com/) and [documentation](http://www.rubydoc.info/github/wycats/thor/index) for details on creating commands.
|
41
|
+
|
42
|
+
When creating Skippy command use the following replacements:
|
43
|
+
|
44
|
+
* Instead of class `Thor`, use `Skippy::Command`
|
45
|
+
* Instead of class `Thor::Group`, use `Skippy::Command::Group`
|
46
|
+
|
47
|
+
## Development
|
48
|
+
|
49
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
50
|
+
|
51
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/thomthom/skippy.
|
56
|
+
|
57
|
+
|
58
|
+
## License
|
59
|
+
|
60
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
61
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"folders":
|
3
|
+
[
|
4
|
+
{
|
5
|
+
"path": "."
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"path": "C:\\Users\\tthomas2\\SourceTree\\thor"
|
9
|
+
}
|
10
|
+
],
|
11
|
+
"settings":
|
12
|
+
{
|
13
|
+
"default_encoding": "UTF-8",
|
14
|
+
"ensure_newline_at_eof_on_save": true,
|
15
|
+
"rulers":
|
16
|
+
[
|
17
|
+
80
|
18
|
+
],
|
19
|
+
"show_encoding": true,
|
20
|
+
"show_line_endings": true,
|
21
|
+
"tab_size": 2,
|
22
|
+
"translate_tabs_to_spaces": true,
|
23
|
+
"trim_trailing_white_space_on_save": true
|
24
|
+
}
|
25
|
+
}
|
data/app/boot.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Set the program name explicitly. Otherwise Thor will use the filename in the
|
4
|
+
# banner for the command help.
|
5
|
+
$PROGRAM_NAME = 'skippy'
|
6
|
+
|
7
|
+
# TODO(thomthom): Temporary set for development without having to set the ENV.
|
8
|
+
# Thor on Windows will by default not use colors. Using Cmder colors will work.
|
9
|
+
# Also in the latest Windows 10 colors appear to work. Not sure how older
|
10
|
+
# versions behave.
|
11
|
+
ENV['THOR_SHELL'] = 'Color' if $stdout.isatty
|
12
|
+
|
13
|
+
# Thor require DL which under Windows and Ruby 2.0 will yield a warning:
|
14
|
+
# DL is deprecated, please use Fiddle
|
15
|
+
#
|
16
|
+
# To avoid this appearing every time this tool is invoked, warnings are
|
17
|
+
# temporarily suppressed.
|
18
|
+
begin
|
19
|
+
original_verbose = $VERBOSE
|
20
|
+
$VERBOSE = nil
|
21
|
+
require 'thor'
|
22
|
+
# The Thor::Runner also needs to be loaded, as Skippy::CLI will call many of
|
23
|
+
# of the same methods - in many cases emulating what it do.
|
24
|
+
require "thor/runner"
|
25
|
+
# This is also needed to be set in order for Thor's utilities to output
|
26
|
+
# command names correctly.
|
27
|
+
$thor_runner = true
|
28
|
+
ensure
|
29
|
+
$VERBOSE = original_verbose
|
30
|
+
end
|
31
|
+
|
32
|
+
# Load skippy components the bootstrapper needs.
|
33
|
+
require 'skippy/app'
|
34
|
+
Skippy::App.boot(__FILE__)
|
35
|
+
|
36
|
+
# Everything is ready to start the CLI.
|
37
|
+
require 'skippy/cli'
|
38
|
+
require 'skippy/error'
|
39
|
+
begin
|
40
|
+
Skippy::CLI.start
|
41
|
+
rescue Skippy::Error => error
|
42
|
+
Skippy::CLI.display_error(error)
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'skippy/namespace'
|
2
|
+
|
3
|
+
class Debug < Skippy::Command
|
4
|
+
|
5
|
+
include Thor::Actions
|
6
|
+
|
7
|
+
desc 'clean', 'Cleans out project files'
|
8
|
+
def clean
|
9
|
+
say "Cleaning out project files..."
|
10
|
+
remove_file Skippy::Project::PROJECT_FILENAME
|
11
|
+
remove_dir 'src'
|
12
|
+
remove_dir 'skippy'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/app/commands/new.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'skippy/app'
|
4
|
+
require 'skippy/group'
|
5
|
+
require 'skippy/project'
|
6
|
+
require 'skippy/template'
|
7
|
+
|
8
|
+
class New < Skippy::Command::Group
|
9
|
+
|
10
|
+
include Thor::Actions
|
11
|
+
|
12
|
+
argument :namespace,
|
13
|
+
:type => :string,
|
14
|
+
:desc => 'The namespace the extension will use'
|
15
|
+
|
16
|
+
class_option :template,
|
17
|
+
:type => :string,
|
18
|
+
:desc => 'The template used to generate the project files',
|
19
|
+
:default => 'standard'
|
20
|
+
|
21
|
+
source_paths << Skippy.app.resources
|
22
|
+
|
23
|
+
attr_reader :project
|
24
|
+
|
25
|
+
def initialize_project
|
26
|
+
@project = Skippy::Project.new(Dir.pwd)
|
27
|
+
if project.exist?
|
28
|
+
raise Skippy::Error, "A project already exist: #{project.filename}"
|
29
|
+
end
|
30
|
+
project.namespace = namespace
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_template
|
34
|
+
template_path = File.join(self.class.source_root, options[:template])
|
35
|
+
unless File.directory?(template_path)
|
36
|
+
raise Skippy::Error, %(Template "#{options[:template]}" not found)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_project_json
|
41
|
+
say ''
|
42
|
+
say 'Generating skippy.json...'
|
43
|
+
say ''
|
44
|
+
say project.filename
|
45
|
+
say project.to_json, :yellow
|
46
|
+
project.save
|
47
|
+
end
|
48
|
+
|
49
|
+
def compile_templates
|
50
|
+
say ''
|
51
|
+
say "Compiling template '#{options[:template]}'..."
|
52
|
+
say ''
|
53
|
+
directory(options[:template], 'src')
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_extension_json
|
57
|
+
extension_info = {
|
58
|
+
name: project.name,
|
59
|
+
description: project.description,
|
60
|
+
creator: project.author,
|
61
|
+
copyright: project.copyright,
|
62
|
+
license: project.license,
|
63
|
+
product_id: project.namespace.to_a.join('_'),
|
64
|
+
version: "0.1.0",
|
65
|
+
build: "1",
|
66
|
+
}
|
67
|
+
json = JSON.pretty_generate(extension_info)
|
68
|
+
json_filename = "src/#{project.namespace.to_underscore}/extension.json"
|
69
|
+
create_file(json_filename, json)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_example_skippy_command
|
73
|
+
copy_file('commands/example.rb', 'skippy/example.rb')
|
74
|
+
end
|
75
|
+
|
76
|
+
def finalize
|
77
|
+
say ''
|
78
|
+
say "Project for #{namespace} created.", :green
|
79
|
+
end
|
80
|
+
|
81
|
+
# These are methods to be used by the template engine when it compiles the
|
82
|
+
# templates and expands the filenames.
|
83
|
+
no_commands do
|
84
|
+
|
85
|
+
# @return [String] The basename for the extension files.
|
86
|
+
def ext_name
|
87
|
+
project.namespace.to_underscore
|
88
|
+
end
|
89
|
+
|
90
|
+
end # no_commands
|
91
|
+
|
92
|
+
# Needed as base for Thor::Actions' file actions.
|
93
|
+
def self.source_root
|
94
|
+
Skippy.app.templates_source_path
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Template < Skippy::Command
|
2
|
+
|
3
|
+
desc 'list', 'List all known templates'
|
4
|
+
def list
|
5
|
+
say 'Available templates:', :yellow
|
6
|
+
templates = Skippy.app.templates
|
7
|
+
if templates.empty?
|
8
|
+
say ' No templates found'
|
9
|
+
else
|
10
|
+
templates.each { |template|
|
11
|
+
say " #{template.name}", :green
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
default_command(:list)
|
16
|
+
|
17
|
+
desc 'install', 'Install a new template'
|
18
|
+
def install(source)
|
19
|
+
raise Skippy::Error, 'Not implemented'
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'remove', 'Remove an installed template'
|
23
|
+
def remove(template_name)
|
24
|
+
raise Skippy::Error, 'Not implemented'
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Hello < Skippy::Command
|
2
|
+
|
3
|
+
desc 'world PERSON', 'Oh, hi there!'
|
4
|
+
def world(person)
|
5
|
+
say "Hello #{person}"
|
6
|
+
end
|
7
|
+
default_command(:world)
|
8
|
+
|
9
|
+
desc 'universe', 'Greets the universe in general'
|
10
|
+
def universe(person)
|
11
|
+
say "DARK IN HERE, ISN'T IT?"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#-------------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Author: <%= project.author %>
|
4
|
+
# Copyright: <%= project.copyright %>
|
5
|
+
# License: <%= project.license %>
|
6
|
+
#
|
7
|
+
#-------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
require 'extensions.rb'
|
12
|
+
require 'sketchup.rb'
|
13
|
+
|
14
|
+
<%= project.namespace.open %>
|
15
|
+
|
16
|
+
file = __FILE__.dup
|
17
|
+
# Account for Ruby encoding bug under Windows.
|
18
|
+
file.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
|
19
|
+
# Support folder should be named the same as the root .rb file.
|
20
|
+
folder_name = File.basename(file, '.*')
|
21
|
+
|
22
|
+
# Path to the root .rb file (this file).
|
23
|
+
PATH_ROOT = File.dirname(file).freeze
|
24
|
+
|
25
|
+
# Path to the support folder.
|
26
|
+
PATH = File.join(PATH_ROOT, folder_name).freeze
|
27
|
+
|
28
|
+
# Extension information.
|
29
|
+
extension_json_file = File.join(PATH, 'extension.json')
|
30
|
+
extension_json = File.read(extension_json_file)
|
31
|
+
EXTENSION = ::JSON.parse(extension_json, symbolize_names: true).freeze
|
32
|
+
|
33
|
+
unless file_loaded?(__FILE__)
|
34
|
+
loader = File.join(PATH, 'bootstrap')
|
35
|
+
@extension = SketchupExtension.new(EXTENSION[:name], loader)
|
36
|
+
@extension.description = EXTENSION[:description]
|
37
|
+
@extension.version = EXTENSION[:version]
|
38
|
+
@extension.copyright = EXTENSION[:copyright]
|
39
|
+
@extension.creator = EXTENSION[:creator]
|
40
|
+
Sketchup.register_extension(@extension, true)
|
41
|
+
end
|
42
|
+
|
43
|
+
<%= project.namespace.close %>
|
44
|
+
|
45
|
+
file_loaded(__FILE__)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sketchup.rb'
|
2
|
+
|
3
|
+
module <%= project.namespace %>
|
4
|
+
|
5
|
+
unless file_loaded?(__FILE__)
|
6
|
+
menu = UI.menu('Plugins').add_submenu(EXTENSION[:name])
|
7
|
+
menu.add_item('Make Magic') { self.make_magic }
|
8
|
+
menu.add_separator
|
9
|
+
menu.add_item('Help...') { self.open_help }
|
10
|
+
file_loaded(__FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.make_magic
|
14
|
+
# Do magic here...
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.open_help
|
18
|
+
UI.openURL(EXTENSION[:url])
|
19
|
+
end
|
20
|
+
|
21
|
+
end # module
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#-------------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Author: <%= project.author %>
|
4
|
+
# Copyright: <%= project.copyright %>
|
5
|
+
# License: <%= project.license %>
|
6
|
+
#
|
7
|
+
#-------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
require 'extensions.rb'
|
12
|
+
require 'sketchup.rb'
|
13
|
+
|
14
|
+
<%= project.namespace.open %>
|
15
|
+
|
16
|
+
file = __FILE__.dup
|
17
|
+
# Account for Ruby encoding bug under Windows.
|
18
|
+
file.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
|
19
|
+
# Support folder should be named the same as the root .rb file.
|
20
|
+
folder_name = File.basename(file, '.*')
|
21
|
+
|
22
|
+
# Path to the root .rb file (this file).
|
23
|
+
PATH_ROOT = File.dirname(file).freeze
|
24
|
+
|
25
|
+
# Path to the support folder.
|
26
|
+
PATH = File.join(PATH_ROOT, folder_name).freeze
|
27
|
+
|
28
|
+
# Extension information.
|
29
|
+
extension_json_file = File.join(PATH, 'extension.json')
|
30
|
+
extension_json = File.read(extension_json_file)
|
31
|
+
EXTENSION = ::JSON.parse(extension_json, symbolize_names: true).freeze
|
32
|
+
|
33
|
+
unless file_loaded?(__FILE__)
|
34
|
+
loader = File.join(PATH, 'bootstrap')
|
35
|
+
@extension = SketchupExtension.new(EXTENSION[:name], loader)
|
36
|
+
@extension.description = EXTENSION[:description]
|
37
|
+
@extension.version = EXTENSION[:version]
|
38
|
+
@extension.copyright = EXTENSION[:copyright]
|
39
|
+
@extension.creator = EXTENSION[:creator]
|
40
|
+
Sketchup.register_extension(@extension, true)
|
41
|
+
end
|
42
|
+
|
43
|
+
<%= project.namespace.close %>
|
44
|
+
|
45
|
+
file_loaded(__FILE__)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'sketchup.rb'
|
2
|
+
|
3
|
+
module <%= project.namespace %>
|
4
|
+
|
5
|
+
unless file_loaded?(__FILE__)
|
6
|
+
menu = UI.menu('Plugins').add_submenu(EXTENSION[:name])
|
7
|
+
menu.add_item('Open Dialog') { self.open_dialog }
|
8
|
+
menu.add_separator
|
9
|
+
menu.add_item('Help...') { self.open_help }
|
10
|
+
file_loaded(__FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.open_dialog
|
14
|
+
file_path = File.join(PATH, 'html', 'dialog.html')
|
15
|
+
@dialog = UI::WebDialog.new
|
16
|
+
@dialog.set_file(file_path)
|
17
|
+
@dialog.show
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.open_help
|
21
|
+
UI.openURL(EXTENSION[:url])
|
22
|
+
end
|
23
|
+
|
24
|
+
end # module
|
data/bin/bundler
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'bundler' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("bundler", "bundler")
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "skippy"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'rake' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("rake", "rake")
|
data/bin/setup
ADDED
data/bin/skippy
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'skippy' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("skippy", "skippy")
|
data/bin/thor
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'thor' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("thor", "thor")
|
data/exe/skippy
ADDED
data/lib/skippy.rb
ADDED
data/lib/skippy/app.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
require 'skippy/command'
|
4
|
+
require 'skippy/group'
|
5
|
+
require 'skippy/template'
|
6
|
+
require 'skippy/skippy'
|
7
|
+
|
8
|
+
class Skippy::App
|
9
|
+
|
10
|
+
# @param [String] boot_loader_path
|
11
|
+
# @return [Skippy::App]
|
12
|
+
def self.boot(boot_loader_path)
|
13
|
+
Skippy.app = Skippy::App.new(boot_loader_path)
|
14
|
+
Skippy.app.boot
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :path
|
18
|
+
|
19
|
+
# @param [String] boot_loader_path
|
20
|
+
def initialize(boot_loader_path)
|
21
|
+
@boot_loader_path = File.expand_path(boot_loader_path)
|
22
|
+
@path = File.dirname(@boot_loader_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def boot
|
26
|
+
boot_commands
|
27
|
+
end
|
28
|
+
|
29
|
+
def resources(item = nil)
|
30
|
+
resource = Pathname.new(File.join(path, 'resources'))
|
31
|
+
item ? resource.join(item) : resource
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Array<String>]
|
35
|
+
def templates_source_path
|
36
|
+
Pathname.new(File.join(path, 'templates'))
|
37
|
+
end
|
38
|
+
|
39
|
+
def templates
|
40
|
+
result = []
|
41
|
+
templates_source_path.entries.each { |entry|
|
42
|
+
template_path = templates_source_path.join(entry)
|
43
|
+
next unless template_path.directory?
|
44
|
+
next if %[. ..].include?(entry.basename.to_s)
|
45
|
+
result << Skippy::Template.new(entry)
|
46
|
+
}
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# @return [Array<String>] loaded files
|
53
|
+
def boot_commands
|
54
|
+
# Load the default skippy commands.
|
55
|
+
path_commands = File.join(path, 'commands')
|
56
|
+
commands_pattern = File.join(path_commands, '*.rb')
|
57
|
+
Dir.glob(commands_pattern) { |filename|
|
58
|
+
require filename
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/skippy/cli.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'skippy/app'
|
2
|
+
require 'skippy/command'
|
3
|
+
require 'skippy/group'
|
4
|
+
require 'skippy/project'
|
5
|
+
require 'skippy/version'
|
6
|
+
|
7
|
+
# The Skippy::CLI class emulates much of what Thor::Runner do. It takes care of
|
8
|
+
# finding skippy projects and loading commands.
|
9
|
+
#
|
10
|
+
# The difference is mainly in how skippy vs thor present the commands.
|
11
|
+
#
|
12
|
+
# TODO(thomthom): ...or should it?
|
13
|
+
# Thor let you install commands globally, where as skippy does not.
|
14
|
+
#
|
15
|
+
# Skippy will list all known commands when invoked without any arguments.
|
16
|
+
#
|
17
|
+
# The code in this class will often refer to thor - when things have been copied
|
18
|
+
# verbatim. Makes it easier to update if needed.
|
19
|
+
class Skippy::CLI < Skippy::Command
|
20
|
+
|
21
|
+
class << self
|
22
|
+
|
23
|
+
# @param [Skippy::Error] error
|
24
|
+
def display_error(error)
|
25
|
+
shell = Thor::Base.shell.new
|
26
|
+
message = " #{error.message} "
|
27
|
+
message = shell.set_color(message, :white)
|
28
|
+
message = shell.set_color(message, :on_red)
|
29
|
+
shell.error message
|
30
|
+
end
|
31
|
+
|
32
|
+
end # Class methods
|
33
|
+
|
34
|
+
default_command :list
|
35
|
+
|
36
|
+
# Verbatim copy from Thor::Runner:
|
37
|
+
# Override Thor#help so it can give information about any class and any method.
|
38
|
+
#
|
39
|
+
def help(meth = nil)
|
40
|
+
if meth && !self.respond_to?(meth)
|
41
|
+
initialize_thorfiles(meth)
|
42
|
+
klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
|
43
|
+
self.class.handle_no_command_error(command, false) if klass.nil?
|
44
|
+
klass.start(["-h", command].compact, :shell => shell)
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Verbatim copy from Thor::Runner:
|
51
|
+
# If a command is not found on Thor::Runner, method missing is invoked and
|
52
|
+
# Thor::Runner is then responsible for finding the command in all classes.
|
53
|
+
#
|
54
|
+
def method_missing(meth, *args)
|
55
|
+
meth = meth.to_s
|
56
|
+
initialize_thorfiles(meth)
|
57
|
+
klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
|
58
|
+
self.class.handle_no_command_error(command, false) if klass.nil?
|
59
|
+
args.unshift(command) if command
|
60
|
+
klass.start(args, :shell => shell)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Verbatim copy from Thor::Runner:
|
64
|
+
desc "list [SEARCH]", "List the available #{$PROGRAM_NAME} commands (--substring means .*SEARCH)"
|
65
|
+
method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
|
66
|
+
def list(search = "")
|
67
|
+
initialize_thorfiles
|
68
|
+
|
69
|
+
search = ".*#{search}" if options["substring"]
|
70
|
+
search = /^#{search}.*/i
|
71
|
+
group = options[:group] || "standard"
|
72
|
+
|
73
|
+
klasses = Thor::Base.subclasses.select do |k|
|
74
|
+
(options[:all] || k.group == group) && k.namespace =~ search
|
75
|
+
end
|
76
|
+
|
77
|
+
display_klasses(false, false, klasses)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Based on Thor::Runner, with exception of program name.
|
83
|
+
def self.banner(command, all = false, subcommand = false)
|
84
|
+
"#{$PROGRAM_NAME} " + command.formatted_usage(self, all, subcommand)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Verbatim copy from Thor::Runner:
|
88
|
+
def self.exit_on_failure?
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
# This is one of the places this runner differ from Thor::Runner. It will
|
93
|
+
# instead load files for the current project.
|
94
|
+
#
|
95
|
+
# TODO(thomthom): Original arguments kept around for now, so avoid altering
|
96
|
+
# the methods that calls this. It might be that these arguments might be
|
97
|
+
# useful for optimizations later.
|
98
|
+
def initialize_thorfiles(_relevant_to = nil, _skip_lookup = false)
|
99
|
+
project = Skippy::Project.new(Dir.pwd)
|
100
|
+
return unless project.exist?
|
101
|
+
project.command_files { |filename|
|
102
|
+
unless Thor::Base.subclass_files.keys.include?(File.expand_path(filename))
|
103
|
+
Thor::Util.load_thorfile(filename, nil, options[:debug])
|
104
|
+
end
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def display_app_banner
|
109
|
+
program_name = shell.set_color($PROGRAM_NAME.capitalize, :green)
|
110
|
+
version = shell.set_color('version', :clear)
|
111
|
+
program_version = shell.set_color(Skippy::VERSION, :yellow)
|
112
|
+
say "#{program_name} #{version} #{program_version}"
|
113
|
+
end
|
114
|
+
|
115
|
+
# Based on Thor::Runner:
|
116
|
+
def display_klasses(with_modules = false, show_internal = false, klasses = Thor::Base.subclasses)
|
117
|
+
unless show_internal
|
118
|
+
klasses -= [
|
119
|
+
Thor, Thor::Runner, Thor::Group,
|
120
|
+
Skippy, Skippy::CLI, Skippy::Command, Skippy::Command::Group
|
121
|
+
]
|
122
|
+
end
|
123
|
+
|
124
|
+
fail Error, "No #{$PROGRAM_NAME.capitalize} commands available" if klasses.empty?
|
125
|
+
|
126
|
+
list = Hash.new { |h, k| h[k] = [] }
|
127
|
+
groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
|
128
|
+
|
129
|
+
# Get classes which inherit from Thor
|
130
|
+
(klasses - groups).each { |k|
|
131
|
+
list[k.namespace.split(":").first] += k.printable_commands(false)
|
132
|
+
}
|
133
|
+
|
134
|
+
# Get classes which inherit from Thor::Base
|
135
|
+
groups.map! { |k| k.printable_commands(false).first }
|
136
|
+
# Thor:Runner put these under 'root', but here we just avoid any name at
|
137
|
+
# all together.
|
138
|
+
list[''] = groups
|
139
|
+
|
140
|
+
display_app_banner
|
141
|
+
say
|
142
|
+
say 'Available commands:', :yellow
|
143
|
+
|
144
|
+
# Align all command descriptions. This means computing a fixed width for
|
145
|
+
# the first column.
|
146
|
+
col_width = list.map { |_, rows|
|
147
|
+
rows.map { |col| col.first.size }.max || 0
|
148
|
+
}.max
|
149
|
+
|
150
|
+
# Order namespaces with default coming first
|
151
|
+
list = list.sort { |a, b|
|
152
|
+
a[0].sub(/^default/, "") <=> b[0].sub(/^default/, "")
|
153
|
+
}
|
154
|
+
list.each { |n, commands|
|
155
|
+
display_commands(n, commands, col_width) unless commands.empty?
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
# Based on Thor::Runner:
|
160
|
+
def display_commands(namespace, list, col_width)
|
161
|
+
list.sort! { |a, b| a[0] <=> b[0] }
|
162
|
+
|
163
|
+
say shell.set_color(namespace, :yellow, true) unless namespace.empty?
|
164
|
+
|
165
|
+
list.each { |row|
|
166
|
+
row[0] = shell.set_color(row[0], :green) + shell.set_color('', :clear)
|
167
|
+
}
|
168
|
+
# TODO(thomthom): For some reason the column appear as half the width.
|
169
|
+
# Not sure why, so for now we apply this hack.
|
170
|
+
# TODO(thomthom): Because of the odd issue with col_width mentioned in
|
171
|
+
# `display_klasses` the table isn't truncated. Can probably re-enable if
|
172
|
+
# the col_width issue is fixed.
|
173
|
+
#print_table(list, :truncate => true, :indent => 2, :colwidth => col_width)
|
174
|
+
width = (col_width + 2) * 2
|
175
|
+
print_table(list, :indent => 2, :colwidth => width)
|
176
|
+
end
|
177
|
+
alias_method :display_tasks, :display_commands
|
178
|
+
|
179
|
+
# Based on Thor::Runner, skipping the yaml stuff:
|
180
|
+
def show_modules
|
181
|
+
info = []
|
182
|
+
labels = %w[Modules Namespaces]
|
183
|
+
|
184
|
+
info << labels
|
185
|
+
info << ["-" * labels[0].size, "-" * labels[1].size]
|
186
|
+
|
187
|
+
print_table info
|
188
|
+
say ""
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Skippy
|
4
|
+
class Command < Thor
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
# Customize the banner as we don't care for the 'skippy' prefix for each
|
9
|
+
# item in the list.
|
10
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
11
|
+
"#{command.formatted_usage(self, true, subcommand)}"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
data/lib/skippy/error.rb
ADDED
data/lib/skippy/group.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
|
3
|
+
require 'skippy/command'
|
4
|
+
|
5
|
+
module Skippy
|
6
|
+
class Command::Group < Thor::Group
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Customize the banner as we don't care for the 'skippy' prefix for each
|
11
|
+
# item in the list.
|
12
|
+
def self.banner
|
13
|
+
"#{self_command.formatted_usage(self, false)}"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Skippy::Namespace
|
2
|
+
|
3
|
+
def initialize(namespace)
|
4
|
+
unless valid?(namespace)
|
5
|
+
raise Skippy::Error, "'#{namespace}' is not a valid Ruby namespace"
|
6
|
+
end
|
7
|
+
@namespace = namespace
|
8
|
+
end
|
9
|
+
|
10
|
+
def basename
|
11
|
+
to_a.last
|
12
|
+
end
|
13
|
+
|
14
|
+
def open
|
15
|
+
@open ||= to_a.map { |part| "module #{part}" }.join("\n")
|
16
|
+
@open
|
17
|
+
end
|
18
|
+
|
19
|
+
def close
|
20
|
+
@close ||= to_a.reverse.map { |part| "end # module #{part}" }.join("\n")
|
21
|
+
@close
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_a
|
25
|
+
parts(@namespace)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_name
|
29
|
+
basename_words(basename).join(' ')
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
@namespace.dup
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_underscore
|
37
|
+
basename_words(basename).map { |word| word.downcase }.join('_')
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def basename_words(namespace_basename)
|
43
|
+
result = namespace_basename.scan(/[[:upper:]]+[[:lower:][:digit:]]*/)
|
44
|
+
result.empty? ? [namespace_basename.dup] : result
|
45
|
+
end
|
46
|
+
|
47
|
+
def parts(namespace)
|
48
|
+
namespace.split('::')
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid?(namespace)
|
52
|
+
parts(namespace).all? { |part| /^[[:upper:]]/.match(part) }
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
require 'skippy/namespace'
|
5
|
+
|
6
|
+
class Skippy::Project
|
7
|
+
|
8
|
+
PROJECT_FILENAME = 'skippy.json'.freeze
|
9
|
+
|
10
|
+
attr_reader :name, :namespace, :path, :author, :copyright, :license
|
11
|
+
attr_accessor :description
|
12
|
+
|
13
|
+
# Initialize a project for the provided path. If the path is within a project
|
14
|
+
# path the base path of the project will be found. Otherwise it's assumed that
|
15
|
+
# the path is the base for a new project.
|
16
|
+
#
|
17
|
+
# @param [Pathname, String] path
|
18
|
+
def initialize(path)
|
19
|
+
@path = find_project_path(path) || Pathname.new(path)
|
20
|
+
@namespace = Skippy::Namespace.new('Untitled')
|
21
|
+
@name = ''
|
22
|
+
@description = ''
|
23
|
+
@author = 'Unknown'
|
24
|
+
@copyright = "Copyright (c) #{Time.now.year}"
|
25
|
+
@license = 'None'
|
26
|
+
end
|
27
|
+
|
28
|
+
# @yield [filename]
|
29
|
+
# @yieldparam [String] filename the path to custom Skippy command
|
30
|
+
def command_files(&block)
|
31
|
+
files_pattern = File.join(path, 'skippy', '**', '*.rb')
|
32
|
+
Dir.glob(files_pattern) { |filename|
|
33
|
+
block.call(filename)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Checks if a project exist on disk. If not it's just transient.
|
38
|
+
def exist?
|
39
|
+
File.exist?(filename)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Full path to the project's configuration file. This file may not exist.
|
43
|
+
# @return [String]
|
44
|
+
def filename
|
45
|
+
File.join(path, PROJECT_FILENAME)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String]
|
49
|
+
def name
|
50
|
+
@name.empty? ? namespace.to_name : @name
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param [String] namespace
|
54
|
+
def namespace=(namespace)
|
55
|
+
@namespace = Skippy::Namespace.new(namespace)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Commits the project to disk.
|
59
|
+
def save
|
60
|
+
File.write(filename, to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String]
|
64
|
+
def to_json
|
65
|
+
project_config = {
|
66
|
+
namespace: namespace,
|
67
|
+
name: name,
|
68
|
+
description: description
|
69
|
+
}
|
70
|
+
JSON.pretty_generate(project_config)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Finds the root of a project based on any path within the project.
|
76
|
+
#
|
77
|
+
# @param [String] path
|
78
|
+
# return [Pathname, nil]
|
79
|
+
def find_project_path(path)
|
80
|
+
pathname = Pathname.new(path)
|
81
|
+
loop do
|
82
|
+
project_file = pathname.join(PROJECT_FILENAME)
|
83
|
+
return pathname if project_file.exist?
|
84
|
+
break if pathname.root?
|
85
|
+
pathname = pathname.parent
|
86
|
+
end
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/skippy.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'skippy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "skippy"
|
8
|
+
spec.version = Skippy::VERSION
|
9
|
+
spec.authors = ["Thomas Thomassen"]
|
10
|
+
spec.email = ["thomas@thomthom.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{CLI development tool for SketchUp extensions.}
|
13
|
+
spec.description = %q{Automate common tasks for SketchUp extension development, including managing library dependencies.}
|
14
|
+
spec.homepage = "https://github.com/thomthom/skippy"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.required_ruby_version = ">= 2.0"
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
21
|
+
end
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
29
|
+
|
30
|
+
spec.add_dependency "thor"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skippy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.a
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thomas Thomassen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Automate common tasks for SketchUp extension development, including managing
|
70
|
+
library dependencies.
|
71
|
+
email:
|
72
|
+
- thomas@thomthom.net
|
73
|
+
executables:
|
74
|
+
- skippy
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- ".vscode/settings.json"
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- Skippy.sublime-project
|
85
|
+
- app/boot.rb
|
86
|
+
- app/commands/debug.rb
|
87
|
+
- app/commands/new.rb
|
88
|
+
- app/commands/template.rb
|
89
|
+
- app/resources/commands/example.rb
|
90
|
+
- app/templates/standard/%ext_name%.rb.tt
|
91
|
+
- app/templates/standard/%ext_name%/main.rb.tt
|
92
|
+
- app/templates/webdialog/extension.rb.erb
|
93
|
+
- app/templates/webdialog/extension/html/dialog.html
|
94
|
+
- app/templates/webdialog/extension/main.rb.erb
|
95
|
+
- bin/bundler
|
96
|
+
- bin/console
|
97
|
+
- bin/rake
|
98
|
+
- bin/setup
|
99
|
+
- bin/skippy
|
100
|
+
- bin/thor
|
101
|
+
- exe/skippy
|
102
|
+
- lib/skippy.rb
|
103
|
+
- lib/skippy/app.rb
|
104
|
+
- lib/skippy/cli.rb
|
105
|
+
- lib/skippy/command.rb
|
106
|
+
- lib/skippy/error.rb
|
107
|
+
- lib/skippy/group.rb
|
108
|
+
- lib/skippy/namespace.rb
|
109
|
+
- lib/skippy/project.rb
|
110
|
+
- lib/skippy/skippy.rb
|
111
|
+
- lib/skippy/version.rb
|
112
|
+
- skippy.gemspec
|
113
|
+
homepage: https://github.com/thomthom/skippy
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '2.0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 1.3.1
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.0.3
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: CLI development tool for SketchUp extensions.
|
137
|
+
test_files: []
|
138
|
+
has_rdoc:
|