skippy 0.1.1.a → 0.2.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 +4 -4
- data/.editorconfig +14 -0
- data/.gitignore +5 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/codeStyleSettings.xml +9 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/inspectionProfiles/Project_Default.xml +8 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/runConfigurations/All_Features.xml +32 -0
- data/.idea/runConfigurations/test__skippy.xml +21 -0
- data/.idea/skippy.iml +83 -0
- data/.idea/vcs.xml +6 -0
- data/.vscode/launch.json +61 -0
- data/.vscode/settings.json +3 -2
- data/.vscode/tasks.json +16 -0
- data/Gemfile +5 -0
- data/Rakefile +4 -4
- data/app/boot.rb +1 -1
- data/app/commands/debug.rb +2 -1
- data/app/commands/lib.rb +46 -0
- data/app/commands/new.rb +4 -3
- data/app/commands/template.rb +3 -3
- data/app/resources/commands/example.rb +1 -1
- data/app/templates/standard/%ext_name%.rb.tt +1 -1
- data/app/templates/webdialog/{extension.rb.erb → %ext_name%.rb.tt} +1 -1
- data/app/templates/webdialog/{extension → %ext_name%}/html/dialog.html +0 -0
- data/app/templates/webdialog/{extension/main.rb.erb → %ext_name%/main.rb.tt} +0 -0
- data/bin/aruba +17 -0
- data/bin/cucumber +17 -0
- data/bin/htmldiff +17 -0
- data/bin/ldiff +17 -0
- data/cSpell.json +18 -0
- data/fixtures/my_lib/skippy.json +5 -0
- data/fixtures/my_lib/src/command.rb +4 -0
- data/fixtures/my_lib/src/geometry.rb +4 -0
- data/fixtures/my_lib/src/tool.rb +4 -0
- data/fixtures/my_project/skippy.json +8 -0
- data/fixtures/my_project/skippy/commands/example.rb +14 -0
- data/fixtures/my_project/src/hello_world.rb +47 -0
- data/fixtures/my_project/src/hello_world/extension.json +10 -0
- data/fixtures/my_project/src/hello_world/main.rb +21 -0
- data/lib/skippy.rb +7 -3
- data/lib/skippy/app.rb +7 -5
- data/lib/skippy/cli.rb +12 -12
- data/lib/skippy/config.rb +135 -0
- data/lib/skippy/config_accessors.rb +43 -0
- data/lib/skippy/error.rb +1 -1
- data/lib/skippy/helpers/file.rb +14 -0
- data/lib/skippy/lib_module.rb +47 -0
- data/lib/skippy/library.rb +57 -0
- data/lib/skippy/library_manager.rb +75 -0
- data/lib/skippy/module_manager.rb +103 -0
- data/lib/skippy/namespace.rb +7 -3
- data/lib/skippy/project.rb +55 -26
- data/lib/skippy/version.rb +1 -1
- data/skippy.gemspec +14 -12
- metadata +69 -8
- data/lib/skippy/skippy.rb +0 -9
data/app/commands/template.rb
CHANGED
@@ -8,18 +8,18 @@ class Template < Skippy::Command
|
|
8
8
|
say ' No templates found'
|
9
9
|
else
|
10
10
|
templates.each { |template|
|
11
|
-
say " #{template}", :green
|
11
|
+
say " #{template.basename}", :green
|
12
12
|
}
|
13
13
|
end
|
14
14
|
end
|
15
15
|
default_command(:list)
|
16
16
|
|
17
|
-
desc 'install', 'Install a new template'
|
17
|
+
desc 'install SOURCE', 'Install a new template'
|
18
18
|
def install(source)
|
19
19
|
raise Skippy::Error, 'Not implemented'
|
20
20
|
end
|
21
21
|
|
22
|
-
desc 'remove', 'Remove an installed template'
|
22
|
+
desc 'remove TEMPLATE', 'Remove an installed template'
|
23
23
|
def remove(template_name)
|
24
24
|
raise Skippy::Error, 'Not implemented'
|
25
25
|
end
|
@@ -31,7 +31,7 @@ require 'sketchup.rb'
|
|
31
31
|
EXTENSION = ::JSON.parse(extension_json, symbolize_names: true).freeze
|
32
32
|
|
33
33
|
unless file_loaded?(__FILE__)
|
34
|
-
loader = File.join(PATH, '
|
34
|
+
loader = File.join(PATH, 'main')
|
35
35
|
@extension = SketchupExtension.new(EXTENSION[:name], loader)
|
36
36
|
@extension.description = EXTENSION[:description]
|
37
37
|
@extension.version = EXTENSION[:version]
|
@@ -31,7 +31,7 @@ require 'sketchup.rb'
|
|
31
31
|
EXTENSION = ::JSON.parse(extension_json, symbolize_names: true).freeze
|
32
32
|
|
33
33
|
unless file_loaded?(__FILE__)
|
34
|
-
loader = File.join(PATH, '
|
34
|
+
loader = File.join(PATH, 'main')
|
35
35
|
@extension = SketchupExtension.new(EXTENSION[:name], loader)
|
36
36
|
@extension.description = EXTENSION[:description]
|
37
37
|
@extension.version = EXTENSION[:version]
|
File without changes
|
File without changes
|
data/bin/aruba
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 'aruba' 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("aruba", "aruba")
|
data/bin/cucumber
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 'cucumber' 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("cucumber", "cucumber")
|
data/bin/htmldiff
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 'htmldiff' 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("diff-lcs", "htmldiff")
|
data/bin/ldiff
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 'ldiff' 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("diff-lcs", "ldiff")
|
data/cSpell.json
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
// cSpell Settings
|
2
|
+
{
|
3
|
+
// Version of the setting file. Always 0.1
|
4
|
+
"version": "0.1",
|
5
|
+
// language - current active spelling language
|
6
|
+
"language": "en",
|
7
|
+
// words - list of words to be always considered correct
|
8
|
+
"words": [
|
9
|
+
"namespace",
|
10
|
+
"yieldparam"
|
11
|
+
],
|
12
|
+
// flagWords - list of words to be always considered incorrect
|
13
|
+
// This is useful for offensive words and common spelling errors.
|
14
|
+
// For example "hte" should be "the"
|
15
|
+
"flagWords": [
|
16
|
+
"hte"
|
17
|
+
]
|
18
|
+
}
|
@@ -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
|
11
|
+
say "DARK IN HERE, ISN'T IT?"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#-------------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Author: Unknown
|
4
|
+
# Copyright: Copyright (c) 2017
|
5
|
+
# License: None
|
6
|
+
#
|
7
|
+
#-------------------------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
require 'extensions.rb'
|
12
|
+
require 'sketchup.rb'
|
13
|
+
|
14
|
+
module Example
|
15
|
+
module HelloWorld
|
16
|
+
|
17
|
+
file = __FILE__.dup
|
18
|
+
# Account for Ruby encoding bug under Windows.
|
19
|
+
file.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
|
20
|
+
# Support folder should be named the same as the root .rb file.
|
21
|
+
folder_name = File.basename(file, '.*')
|
22
|
+
|
23
|
+
# Path to the root .rb file (this file).
|
24
|
+
PATH_ROOT = File.dirname(file).freeze
|
25
|
+
|
26
|
+
# Path to the support folder.
|
27
|
+
PATH = File.join(PATH_ROOT, folder_name).freeze
|
28
|
+
|
29
|
+
# Extension information.
|
30
|
+
extension_json_file = File.join(PATH, 'extension.json')
|
31
|
+
extension_json = File.read(extension_json_file)
|
32
|
+
EXTENSION = ::JSON.parse(extension_json, symbolize_names: true).freeze
|
33
|
+
|
34
|
+
unless file_loaded?(__FILE__)
|
35
|
+
loader = File.join(PATH, 'main')
|
36
|
+
@extension = SketchupExtension.new(EXTENSION[:name], loader)
|
37
|
+
@extension.description = EXTENSION[:description]
|
38
|
+
@extension.version = EXTENSION[:version]
|
39
|
+
@extension.copyright = EXTENSION[:copyright]
|
40
|
+
@extension.creator = EXTENSION[:creator]
|
41
|
+
Sketchup.register_extension(@extension, true)
|
42
|
+
end
|
43
|
+
|
44
|
+
end # module HelloWorld
|
45
|
+
end # module Example
|
46
|
+
|
47
|
+
file_loaded(__FILE__)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sketchup.rb'
|
2
|
+
|
3
|
+
module Example::HelloWorld
|
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
|
data/lib/skippy.rb
CHANGED
data/lib/skippy/app.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
|
3
|
+
require 'skippy'
|
3
4
|
require 'skippy/command'
|
4
5
|
require 'skippy/group'
|
5
|
-
require 'skippy/skippy'
|
6
6
|
|
7
7
|
class Skippy::App
|
8
8
|
|
@@ -11,6 +11,7 @@ class Skippy::App
|
|
11
11
|
def self.boot(boot_loader_path)
|
12
12
|
Skippy.app = Skippy::App.new(boot_loader_path)
|
13
13
|
Skippy.app.boot
|
14
|
+
Skippy.app
|
14
15
|
end
|
15
16
|
|
16
17
|
attr_reader :path
|
@@ -35,27 +36,28 @@ class Skippy::App
|
|
35
36
|
Pathname.new(File.join(path, 'templates'))
|
36
37
|
end
|
37
38
|
|
39
|
+
# @return [Array<Pathname>]
|
38
40
|
def templates
|
39
41
|
result = []
|
40
42
|
templates_source_path.entries.each { |entry|
|
41
43
|
template_path = templates_source_path.join(entry)
|
42
44
|
next unless template_path.directory?
|
43
|
-
next if %[. ..].include?(entry.basename.to_s)
|
44
|
-
result << entry
|
45
|
+
next if %w[. ..].include?(entry.basename.to_s)
|
46
|
+
result << entry.expand_path(templates_source_path)
|
45
47
|
}
|
46
48
|
result
|
47
49
|
end
|
48
50
|
|
49
51
|
private
|
50
52
|
|
51
|
-
# @return [Array<String>] loaded files
|
52
53
|
def boot_commands
|
53
54
|
# Load the default skippy commands.
|
54
55
|
path_commands = File.join(path, 'commands')
|
55
56
|
commands_pattern = File.join(path_commands, '*.rb')
|
56
57
|
Dir.glob(commands_pattern) { |filename|
|
58
|
+
# noinspection RubyResolve
|
57
59
|
require filename
|
58
60
|
}
|
59
61
|
end
|
60
62
|
|
61
|
-
end
|
63
|
+
end
|
data/lib/skippy/cli.rb
CHANGED
@@ -31,11 +31,11 @@ class Skippy::CLI < Skippy::Command
|
|
31
31
|
|
32
32
|
end # Class methods
|
33
33
|
|
34
|
-
map
|
34
|
+
map '-v' => :version
|
35
35
|
|
36
36
|
default_command :list
|
37
37
|
|
38
|
-
desc
|
38
|
+
desc 'version', 'Show Skippy version'
|
39
39
|
def version
|
40
40
|
display_app_banner
|
41
41
|
end
|
@@ -48,7 +48,7 @@ class Skippy::CLI < Skippy::Command
|
|
48
48
|
initialize_thorfiles(meth)
|
49
49
|
klass, command = Thor::Util.find_class_and_command_by_namespace(meth)
|
50
50
|
self.class.handle_no_command_error(command, false) if klass.nil?
|
51
|
-
klass.start([
|
51
|
+
klass.start(['-h', command].compact, :shell => shell)
|
52
52
|
else
|
53
53
|
super
|
54
54
|
end
|
@@ -68,14 +68,14 @@ class Skippy::CLI < Skippy::Command
|
|
68
68
|
end
|
69
69
|
|
70
70
|
# Verbatim copy from Thor::Runner:
|
71
|
-
desc
|
71
|
+
desc 'list [SEARCH]', "List the available #{$PROGRAM_NAME} commands (--substring means .*SEARCH)"
|
72
72
|
method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
|
73
|
-
def list(search =
|
73
|
+
def list(search = '')
|
74
74
|
initialize_thorfiles
|
75
75
|
|
76
|
-
search = ".*#{search}" if options[
|
76
|
+
search = ".*#{search}" if options['substring']
|
77
77
|
search = /^#{search}.*/i
|
78
|
-
group = options[:group] ||
|
78
|
+
group = options[:group] || 'standard'
|
79
79
|
|
80
80
|
klasses = Thor::Base.subclasses.select do |k|
|
81
81
|
(options[:all] || k.group == group) && k.namespace =~ search
|
@@ -120,7 +120,7 @@ class Skippy::CLI < Skippy::Command
|
|
120
120
|
end
|
121
121
|
|
122
122
|
# Based on Thor::Runner:
|
123
|
-
def display_klasses(
|
123
|
+
def display_klasses(_with_modules = false, show_internal = false, klasses = Thor::Base.subclasses)
|
124
124
|
unless show_internal
|
125
125
|
klasses -= [
|
126
126
|
Thor, Thor::Runner, Thor::Group,
|
@@ -135,7 +135,7 @@ class Skippy::CLI < Skippy::Command
|
|
135
135
|
|
136
136
|
# Get classes which inherit from Thor
|
137
137
|
(klasses - groups).each { |k|
|
138
|
-
list[k.namespace.split(
|
138
|
+
list[k.namespace.split(':').first] += k.printable_commands(false)
|
139
139
|
}
|
140
140
|
|
141
141
|
# Get classes which inherit from Thor::Base
|
@@ -156,7 +156,7 @@ class Skippy::CLI < Skippy::Command
|
|
156
156
|
|
157
157
|
# Order namespaces with default coming first
|
158
158
|
list = list.sort { |a, b|
|
159
|
-
a[0].sub(/^default/,
|
159
|
+
a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '')
|
160
160
|
}
|
161
161
|
list.each { |n, commands|
|
162
162
|
display_commands(n, commands, col_width) unless commands.empty?
|
@@ -189,10 +189,10 @@ class Skippy::CLI < Skippy::Command
|
|
189
189
|
labels = %w[Modules Namespaces]
|
190
190
|
|
191
191
|
info << labels
|
192
|
-
info << [
|
192
|
+
info << ['-' * labels[0].size, '-' * labels[1].size]
|
193
193
|
|
194
194
|
print_table info
|
195
|
-
say
|
195
|
+
say ''
|
196
196
|
end
|
197
197
|
|
198
198
|
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
require 'skippy/error'
|
5
|
+
|
6
|
+
class Skippy::Config < Hash
|
7
|
+
|
8
|
+
attr_accessor :path
|
9
|
+
|
10
|
+
class MissingPathError < Skippy::Error; end
|
11
|
+
|
12
|
+
def self.load(path, defaults = {})
|
13
|
+
if path.exist?
|
14
|
+
json = File.read(path)
|
15
|
+
config = JSON.parse(json,
|
16
|
+
symbolize_names: true,
|
17
|
+
object_class: self
|
18
|
+
)
|
19
|
+
else
|
20
|
+
config = self.new
|
21
|
+
end
|
22
|
+
# Need to merge nested defaults.
|
23
|
+
config.merge!(defaults) { |_key, value, default|
|
24
|
+
if value.is_a?(Hash) && default.is_a?(Hash)
|
25
|
+
# Deep merge in order to merge nested hashes.
|
26
|
+
# Note: This currently doesn't merge arrays.
|
27
|
+
# http://stackoverflow.com/a/9381776/486990
|
28
|
+
merger = proc { |_k, v1, v2|
|
29
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
|
30
|
+
}
|
31
|
+
default.merge(value, &merger)
|
32
|
+
else
|
33
|
+
value || default
|
34
|
+
end
|
35
|
+
}
|
36
|
+
config.path = path
|
37
|
+
config
|
38
|
+
end
|
39
|
+
|
40
|
+
def get(key_path, default = nil)
|
41
|
+
get_item(key_path) || default
|
42
|
+
end
|
43
|
+
|
44
|
+
def set(key_path, value)
|
45
|
+
set_item(key_path, value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def push(key_path, value)
|
49
|
+
item = get_item(key_path)
|
50
|
+
item = set_item(key_path, []) if item.nil?
|
51
|
+
raise ArgumentError, 'key path is not an Array' unless item.is_a?(Array)
|
52
|
+
item << value
|
53
|
+
end
|
54
|
+
|
55
|
+
def export(target_path)
|
56
|
+
json = JSON.pretty_generate(self)
|
57
|
+
File.write(target_path, json)
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_as(target_path)
|
62
|
+
export(target_path)
|
63
|
+
@path = target_path
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def save
|
68
|
+
raise MissingPathError if path.nil?
|
69
|
+
export(path)
|
70
|
+
end
|
71
|
+
|
72
|
+
def path=(new_path)
|
73
|
+
@path = Pathname.new(new_path)
|
74
|
+
end
|
75
|
+
|
76
|
+
def update(hash)
|
77
|
+
if hash.keys.first.is_a?(String)
|
78
|
+
update_from_key_paths(hash)
|
79
|
+
else
|
80
|
+
update_from_hash(hash)
|
81
|
+
end
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
def inspect
|
86
|
+
"#{super}:#{self.class.name}"
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def update_from_hash(hash)
|
92
|
+
merger = proc { |_key, v1, v2|
|
93
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
|
94
|
+
}
|
95
|
+
merge!(hash, &merger)
|
96
|
+
end
|
97
|
+
|
98
|
+
def update_from_key_paths(key_paths)
|
99
|
+
key_paths.each { |key_path, value|
|
100
|
+
set(key_path, value)
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
def key_parts(key_path)
|
105
|
+
if key_path.is_a?(Symbol)
|
106
|
+
[key_path]
|
107
|
+
else
|
108
|
+
key_path.split('/').map { |key| key.intern }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_item(key_path)
|
113
|
+
parts = key_parts(key_path)
|
114
|
+
return nil if parts.empty?
|
115
|
+
item = self
|
116
|
+
parts.each { |key|
|
117
|
+
return nil if item.nil?
|
118
|
+
item = item[key]
|
119
|
+
}
|
120
|
+
item
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_item(key_path, value)
|
124
|
+
item = self
|
125
|
+
parts = key_parts(key_path)
|
126
|
+
last_key = parts.pop
|
127
|
+
parts.each { |key|
|
128
|
+
item[key] ||= self.class.new
|
129
|
+
item = item[key]
|
130
|
+
}
|
131
|
+
item[last_key] = value
|
132
|
+
value
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|