skippy 0.4.0.a → 0.5.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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skippy::Helpers
2
4
  module File
3
5
 
@@ -7,6 +9,7 @@ module Skippy::Helpers
7
9
  # @return [Array<Pathname>]
8
10
  def directories(pathname)
9
11
  return [] unless pathname.exist?
12
+
10
13
  pathname.children.select(&:directory?)
11
14
  end
12
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'git'
2
4
  require 'naturally'
3
5
  require 'pathname'
@@ -32,8 +34,7 @@ class Skippy::GitLibraryInstaller < Skippy::LibraryInstaller
32
34
  git.checkout(previous_commit) if previous_commit
33
35
  raise
34
36
  end
35
- library = Skippy::Library.new(target, source: source)
36
- library
37
+ Skippy::Library.new(target, source: source)
37
38
  end
38
39
 
39
40
  private
@@ -55,18 +56,19 @@ class Skippy::GitLibraryInstaller < Skippy::LibraryInstaller
55
56
  git = Git.open(target)
56
57
  previous_commit = git.object('HEAD^').class
57
58
  git.reset_hard
58
- git.pull
59
+ git.fetch
59
60
  [git, previous_commit]
60
61
  end
61
62
 
62
63
  # @param [Git::Base]
63
64
  # @param [String] branch
64
65
  def checkout_branch(git, branch)
65
- branches = git.braches.map(&:name)
66
+ branches = git.branches.map(&:name)
66
67
  info "Branches: #{branches.inspect}"
67
68
  unless branches.include?(branch)
68
69
  raise Skippy::BranchNotFound, "Found no branch named: '#{branch}'"
69
70
  end
71
+
70
72
  git.checkout(branch)
71
73
  nil
72
74
  end
@@ -77,6 +79,7 @@ class Skippy::GitLibraryInstaller < Skippy::LibraryInstaller
77
79
  tags = Naturally.sort_by(git.tags, :name)
78
80
  tag = latest_version?(version) ? tags.last : resolve_tag(tags, version)
79
81
  raise Skippy::TagNotFound, "Found no version: '#{version}'" if tag.nil?
82
+
80
83
  git.checkout(tag)
81
84
  # Verify the library version with the tagged version.
82
85
  target = path.join(source.lib_path)
@@ -97,6 +100,7 @@ class Skippy::GitLibraryInstaller < Skippy::LibraryInstaller
97
100
  requirement = Gem::Requirement.new(version)
98
101
  tags.reverse.find { |tag|
99
102
  next false unless Gem::Version.correct?(tag.name)
103
+
100
104
  tag_version = Gem::Version.new(tag.name)
101
105
  requirement.satisfied_by?(tag_version)
102
106
  }
@@ -104,7 +108,7 @@ class Skippy::GitLibraryInstaller < Skippy::LibraryInstaller
104
108
 
105
109
  # @param [String] version
106
110
  def edge_version?(version)
107
- version && version.casecmp('edge').zero?
111
+ version&.casecmp('edge')&.zero?
108
112
  end
109
113
 
110
114
  # @param [String] version
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'skippy/installer'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'skippy/lib_source'
2
4
  require 'skippy/library'
3
5
  require 'skippy/project'
@@ -28,7 +30,7 @@ class Skippy::LibraryInstaller
28
30
  # @param [Symbol] type
29
31
  # @param [String] message
30
32
  def status(type, message)
31
- @messager.call(type, message) if @messager
33
+ @messager&.call(type, message)
32
34
  end
33
35
 
34
36
  # @param [String] message
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'skippy/library'
@@ -13,6 +15,7 @@ class Skippy::LibModule
13
15
  def initialize(library, path)
14
16
  @path = Pathname.new(path)
15
17
  raise ModuleNotFoundError, @path.to_s unless @path.file?
18
+
16
19
  @library = library
17
20
  end
18
21
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'digest'
2
4
  require 'net/http'
3
5
  require 'pathname'
@@ -40,6 +42,7 @@ class Skippy::LibrarySource
40
42
  # @return [String, nil]
41
43
  def requirement
42
44
  return nil if @options[:requirement].nil?
45
+
43
46
  # Normalize the version requirement pattern.
44
47
  parts = Gem::Requirement.parse(@options[:requirement])
45
48
  # .parse will from '1.2.3' return ['=', '1.2.3']. Don't need that.
@@ -117,7 +120,10 @@ class Skippy::LibrarySource
117
120
  # @param [String] source
118
121
  # @return [String]
119
122
  def resolve_from_git_uri(source)
120
- uri = URI.parse(source)
123
+ # This can be a local Windows path, normalize path separators to allow the
124
+ # path to be parsed.
125
+ normalized = source.tr('\\', '/')
126
+ uri = URI.parse(normalized)
121
127
  # When logged in, BitBucket will display a URI with the user's username.
122
128
  uri.user = ''
123
129
  uri.to_s
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'pathname'
3
5
 
@@ -12,7 +14,7 @@ class Skippy::Library
12
14
 
13
15
  include Skippy::Helpers::File
14
16
 
15
- CONFIG_FILENAME = 'skippy.json'.freeze
17
+ CONFIG_FILENAME = 'skippy.json'
16
18
 
17
19
  attr_reader :path, :source, :requirement
18
20
 
@@ -28,8 +30,10 @@ class Skippy::Library
28
30
  @path = Pathname.new(path)
29
31
  raise LibraryNotFoundError, @path.to_s unless @path.directory?
30
32
  raise LibraryNotFoundError, config_file.to_s unless config_file.exist?
33
+
31
34
  @config = Skippy::Config.load(config_file)
32
35
  raise LibraryNotFoundError, 'Not a Skippy Library' unless @config[:library]
36
+
33
37
  @source = source
34
38
  end
35
39
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'git'
2
4
  require 'json'
3
5
  require 'naturally'
@@ -29,13 +31,14 @@ class Skippy::LibraryManager
29
31
  # @param [Skippy::Project] project
30
32
  def initialize(project)
31
33
  raise TypeError, 'expected a Project' unless project.is_a?(Skippy::Project)
34
+
32
35
  @project = project
33
36
  @libraries = SortedSet.new(discover_libraries)
34
37
  end
35
38
 
36
39
  # @yield [Skippy::Library]
37
- def each
38
- @libraries.each { |library| yield library }
40
+ def each(&block)
41
+ @libraries.each(&block)
39
42
  self
40
43
  end
41
44
 
@@ -56,8 +59,10 @@ class Skippy::LibraryManager
56
59
  if library_name.nil? || module_name.nil?
57
60
  raise ArgumentError, 'expected a module path'
58
61
  end
62
+
59
63
  library = find_library(library_name)
60
64
  return nil if library.nil?
65
+
61
66
  library.modules.find { |mod| mod.basename.casecmp(module_name).zero? }
62
67
  end
63
68
 
@@ -77,11 +82,12 @@ class Skippy::LibraryManager
77
82
  # @return [Skippy::Library]
78
83
  def install(source, options = {})
79
84
  raise Skippy::Project::ProjectNotSavedError unless project.exist?
85
+
80
86
  lib_source = Skippy::LibrarySource.new(project, source, options)
81
87
 
82
88
  installer = get_installer(lib_source)
83
89
  if block_given?
84
- installer.on_status { |type, message|
90
+ installer.on_status { |type, message| # rubocop:disable Style/ExplicitBlockArgument
85
91
  yield type, message
86
92
  }
87
93
  end
@@ -99,8 +105,10 @@ class Skippy::LibraryManager
99
105
  # @return [Skippy::Library]
100
106
  def uninstall(lib)
101
107
  raise Skippy::Project::ProjectNotSavedError unless project.exist?
108
+
102
109
  library = lib.is_a?(Skippy::Library) ? lib : find_library(lib)
103
110
  raise Skippy::LibraryNotFound, 'Library not found' if library.nil?
111
+
104
112
  # Uninstall modules first - using the module manager.
105
113
  vendor_path = project.modules.vendor_path
106
114
  vendor_module_path = vendor_path.join(library.name)
@@ -113,9 +121,11 @@ class Skippy::LibraryManager
113
121
  vendor_path.rmdir
114
122
  end
115
123
  raise 'Unable to remove vendor modules' if vendor_module_path.exist?
124
+
116
125
  # Now the library itself is safe to remove.
117
126
  library.path.rmtree if library.path.exist?
118
127
  raise 'Unable to remove library' if library.path.exist?
128
+
119
129
  @libraries.delete(library)
120
130
  library
121
131
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
  require 'json'
3
5
  require 'pathname'
@@ -17,13 +19,14 @@ class Skippy::ModuleManager
17
19
  # @param [Skippy::Project] project
18
20
  def initialize(project)
19
21
  raise TypeError, 'expected a Project' unless project.is_a?(Skippy::Project)
22
+
20
23
  @project = project
21
24
  @modules = SortedSet.new(discover_modules)
22
25
  end
23
26
 
24
27
  # @yield [Skippy::LibModule]
25
- def each
26
- @modules.each { |lib_module| yield lib_module }
28
+ def each(&block)
29
+ @modules.each(&block)
27
30
  self
28
31
  end
29
32
 
@@ -40,7 +43,7 @@ class Skippy::ModuleManager
40
43
  # @param [Skippy::LibModule, String] lib_module
41
44
  def installed?(lib_module)
42
45
  module_name = lib_module.name
43
- modules = project && project.config.get(:modules, [])
46
+ modules = project&.config&.get(:modules, [])
44
47
  modules.any? { |mod| mod.casecmp(module_name).zero? }
45
48
  end
46
49
 
@@ -48,6 +51,7 @@ class Skippy::ModuleManager
48
51
  # @return [Skippy::LibModule]
49
52
  def use(module_name)
50
53
  raise Skippy::Project::ProjectNotSavedError unless project.exist?
54
+
51
55
  lib_module = project.libraries.find_module_or_fail(module_name)
52
56
 
53
57
  source = lib_module.path
@@ -63,6 +67,7 @@ class Skippy::ModuleManager
63
67
  # @return [Array<Skippy::LibModule>]
64
68
  def update(library)
65
69
  raise Skippy::Project::ProjectNotSavedError unless project.exist?
70
+
66
71
  installed = select { |mod| mod.library.name.casecmp(library.name).zero? }
67
72
  installed.each { |mod| use(mod.name) }
68
73
  installed
@@ -72,6 +77,7 @@ class Skippy::ModuleManager
72
77
  # @return [Skippy::LibModule]
73
78
  def remove(module_name)
74
79
  raise Skippy::Project::ProjectNotSavedError unless project.exist?
80
+
75
81
  lib_module = project.libraries.find_module_or_fail(module_name)
76
82
 
77
83
  target = vendor_path.join(lib_module.library.name, lib_module.path.basename)
@@ -103,9 +109,11 @@ class Skippy::ModuleManager
103
109
  project.libraries.each { |library|
104
110
  library_vendor_path = vendor_path.join(library.name)
105
111
  next unless library_vendor_path.directory?
112
+
106
113
  library_vendor_path.each_child { |module_file|
107
114
  next unless module_file.file?
108
115
  next unless module_file.extname.casecmp('.rb').zero?
116
+
109
117
  modules << Skippy::LibModule.new(library, module_file)
110
118
  }
111
119
  }
@@ -122,6 +130,7 @@ class Skippy::ModuleManager
122
130
  basename = source.basename('.*')
123
131
  source_support_folder = source.parent.join(basename)
124
132
  return unless source_support_folder.directory?
133
+
125
134
  target_support_folder = target.parent.join(basename)
126
135
  copy_directory(lib_module, source_support_folder, target_support_folder)
127
136
  end
@@ -133,6 +142,7 @@ class Skippy::ModuleManager
133
142
  Dir.glob("#{source_path}/**/*") { |filename|
134
143
  source = Pathname.new(filename)
135
144
  next unless source.file?
145
+
136
146
  relative_path = source.relative_path_from(source_path)
137
147
  target = target_path.join(relative_path)
138
148
  copy_file(lib_module, source, target)
@@ -150,7 +160,7 @@ class Skippy::ModuleManager
150
160
  transform_module(content)
151
161
  File.write(target, content)
152
162
  else
153
- File.copy(source, target)
163
+ FileUtils.copy(source, target)
154
164
  end
155
165
  end
156
166
 
@@ -164,7 +174,7 @@ class Skippy::ModuleManager
164
174
  content
165
175
  end
166
176
 
167
- LIB_REQUIRE_PATTERN = %r{(\brequire ["'])(modules)(/[^"']*["'])}
177
+ LIB_REQUIRE_PATTERN = %r{(\brequire ["'])(modules)(/[^"']*["'])}.freeze
168
178
 
169
179
  # Transform the require statements to the target destination.
170
180
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'skippy/error'
2
4
 
3
5
  class Skippy::Namespace
@@ -6,6 +8,7 @@ class Skippy::Namespace
6
8
  unless valid?(namespace)
7
9
  raise Skippy::Error, "'#{namespace}' is not a valid Ruby namespace"
8
10
  end
11
+
9
12
  @namespace = namespace
10
13
  end
11
14
 
@@ -24,6 +27,7 @@ class Skippy::Namespace
24
27
  def short_name
25
28
  items = to_a
26
29
  return to_s unless items.size > 1
30
+
27
31
  initials = items.first.scan(/[[:upper:]]/)
28
32
  prefix = initials.size > 1 ? initials.join : items.first[0, 2]
29
33
  "#{prefix}_#{items.last}"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Skippy::OSCommon
2
4
 
3
5
  # @param [String] command
@@ -23,4 +25,11 @@ class Skippy::OSCommon
23
25
  raise NotImplementedError
24
26
  end
25
27
 
28
+ # @param [String] path
29
+ # @return [Integer, nil]
30
+ def sketchup_version_from_path(path)
31
+ match = File.basename(path).match(/[0-9.]+/)
32
+ match ? match[0].to_i : nil
33
+ end
34
+
26
35
  end
data/lib/skippy/os/mac.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'skippy/os/common'
2
4
  require 'skippy/sketchup/app'
3
5
 
@@ -18,12 +20,14 @@ class Skippy::OSMac < Skippy::OSCommon
18
20
  Dir.glob(pattern) { |path|
19
21
  app = File.join(path, 'SketchUp.app')
20
22
  debug_lib = File.join(app, 'Contents/Frameworks/SURubyDebugger.dylib')
21
- version = File.basename(path).match(/[0-9.]+$/)[0].to_i
23
+ version = sketchup_version_from_path(path)
24
+ next unless version
25
+
22
26
  apps << Skippy::SketchUpApp.from_hash(
23
27
  executable: app,
24
28
  version: version,
25
29
  can_debug: File.exist?(debug_lib),
26
- is64bit: version > 2015,
30
+ is64bit: version > 2015
27
31
  )
28
32
  }
29
33
  apps.sort_by(&:version)
data/lib/skippy/os/win.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'skippy/os/common'
2
4
  require 'skippy/sketchup/app'
3
5
 
4
6
  class Skippy::OSWin < Skippy::OSCommon
5
7
 
6
- # Note: This is not a good indication to 32bit bs 64bit. It's a naive
8
+ # NOTE: This is not a good indication to 32bit bs 64bit. It's a naive
7
9
  # assumption that will fail when SketchUp is installed to a
8
10
  # non-standard location.
9
11
  SYSTEM_32BIT = ENV['ProgramFiles(x86)'].nil? && ENV['ProgramW6432'].nil?
@@ -28,12 +30,14 @@ class Skippy::OSWin < Skippy::OSCommon
28
30
  Dir.glob(pattern) { |path|
29
31
  exe = File.join(path, 'SketchUp.exe')
30
32
  debug_dll = File.join(path, 'SURubyDebugger.dll')
31
- version = File.basename(path).match(/[0-9.]+$/)[0].to_i
33
+ version = sketchup_version_from_path(path)
34
+ next unless version
35
+
32
36
  apps << Skippy::SketchUpApp.from_hash(
33
37
  executable: exe,
34
38
  version: version,
35
39
  can_debug: File.exist?(debug_dll),
36
- is64bit: SYSTEM_64BIT && path.start_with?("#{PROGRAM_FILES_64BIT}/"),
40
+ is64bit: SYSTEM_64BIT && path.start_with?("#{PROGRAM_FILES_64BIT}/")
37
41
  )
38
42
  }
39
43
  }
data/lib/skippy/os.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skippy
2
4
 
3
5
  if RUBY_PLATFORM =~ /darwin/
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'pathname'
3
5
 
@@ -15,7 +17,7 @@ class Skippy::Project
15
17
 
16
18
  include Skippy::Helpers::File
17
19
 
18
- PROJECT_FILENAME = 'skippy.json'.freeze
20
+ PROJECT_FILENAME = 'skippy.json'
19
21
 
20
22
  attr_reader :config
21
23
  attr_reader :libraries
@@ -36,6 +38,7 @@ class Skippy::Project
36
38
  def self.current_or_fail
37
39
  project = current
38
40
  raise ProjectNotFoundError, project.filename unless project.exist?
41
+
39
42
  project
40
43
  end
41
44
 
@@ -66,11 +69,9 @@ class Skippy::Project
66
69
 
67
70
  # @yield [filename]
68
71
  # @yieldparam [String] filename the path to custom Skippy command
69
- def command_files
72
+ def command_files(&block)
70
73
  files_pattern = File.join(path, 'skippy', '**', '*.rb')
71
- Dir.glob(files_pattern) { |filename|
72
- yield filename
73
- }
74
+ Dir.glob(files_pattern, &block)
74
75
  end
75
76
 
76
77
  # Checks if a project exist on disk. If not it's just transient.
@@ -108,8 +109,8 @@ class Skippy::Project
108
109
  end
109
110
 
110
111
  # @return [String]
111
- def to_json
112
- JSON.pretty_generate(@config)
112
+ def to_json(*args)
113
+ JSON.pretty_generate(@config, *args)
113
114
  end
114
115
 
115
116
  private
@@ -141,6 +142,7 @@ class Skippy::Project
141
142
  project_file = pathname.join(PROJECT_FILENAME)
142
143
  return pathname if project_file.exist?
143
144
  break if pathname.root?
145
+
144
146
  pathname = pathname.parent
145
147
  end
146
148
  nil
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skippy
2
4
 
3
5
  SketchUpApp = Struct.new(:executable, :version, :can_debug, :is64bit) do
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Skippy
2
4
 
3
- VERSION = '0.4.0.a'.freeze
5
+ VERSION = '0.5.0.a'
4
6
 
5
7
  end
data/lib/skippy.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'skippy/version'
2
4
 
3
5
  module Skippy
data/skippy.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.homepage = 'https://github.com/thomthom/skippy'
16
16
  spec.license = 'MIT'
17
17
 
18
- spec.required_ruby_version = '>= 2.0'
18
+ spec.required_ruby_version = '>= 2.3'
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
21
  f.match(%r{^(test|spec|features)/})
@@ -26,13 +26,10 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency 'git', '~> 1.3'
28
28
  spec.add_dependency 'naturally', '~> 2.1'
29
- spec.add_dependency 'thor', '~> 0.19'
29
+ spec.add_dependency 'thor', '>= 0.19', '< 2.0'
30
30
 
31
- spec.add_development_dependency 'bundler', '~> 1.13'
32
- spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'bundler', '>= 1.15.0', '< 3.0'
32
+ spec.add_development_dependency 'rake', '~> 12.3.3'
33
33
  spec.add_development_dependency 'minitest', '~> 5.0'
34
- # TODO(thomthom): Need to lock to 2.3 because 2.4 fails with the custom
35
- # aruba build.
36
- spec.add_development_dependency 'cucumber', '~> 2.3.0'
37
- spec.add_development_dependency 'aruba', '~> 0.14.1'
34
+ spec.add_development_dependency 'aruba', '~> 1.0'
38
35
  end