lib/skippy/module_manager.rb in skippy-0.2.0.a vs lib/skippy/module_manager.rb in skippy-0.3.0.a
- old
+ new
@@ -1,7 +1,9 @@
+require 'fileutils'
require 'json'
require 'pathname'
+require 'set'
require 'skippy/helpers/file'
require 'skippy/lib_module'
require 'skippy/project'
@@ -14,90 +16,166 @@
# @param [Skippy::Project] project
def initialize(project)
raise TypeError, 'expected a Project' unless project.is_a?(Skippy::Project)
@project = project
+ @modules = SortedSet.new(discover_modules)
end
# @yield [Skippy::LibModule]
def each
- directories(path).each { |library_path|
- library_path.each_child { |module_file|
- next unless module_file.file?
- next unless module_file.extname == '.rb'
- yield Skippy::LibModule.new(module_file)
- }
- }
+ @modules.each { |lib_module| yield lib_module }
self
end
def empty?
to_a.empty?
end
# @param [String] module_name
# @return [Skippy::LibModule, nil]
def find_module(module_name)
- find { |lib_module| lib_module.name == module_name }
+ find { |lib_module| lib_module.name.casecmp(module_name).zero? }
end
# @param [Skippy::LibModule, String] lib_module
def installed?(lib_module)
- module_name = lib_module.is_a?(Skippy::LibModule) ? lib_module.name : lib_module
- project = Skippy::Project.current
- project && project.config.get(:modules, []).any? { |mod| mod == module_name }
+ module_name = lib_module.name
+ modules = project && project.config.get(:modules, [])
+ modules.any? { |mod| mod.casecmp(module_name).zero? }
end
# @param [String] module_name
# @return [Skippy::LibModule]
def use(module_name)
raise Skippy::Project::ProjectNotSavedError unless project.exist?
+ lib_module = project.libraries.find_module_or_fail(module_name)
- lib_module = project.libraries.find_module(module_name)
- raise Skippy::LibModule::ModuleNotFoundError,
- "module '#{module_name}' not found" if lib_module.nil?
-
source = lib_module.path
- target = path.join(lib_module.library.name, lib_module.path.basename)
+ target = vendor_path.join(lib_module.library.name, lib_module.path.basename)
- copy_module(source, target)
+ copy_module(lib_module, source, target)
+ @modules << lib_module
- project.config.push(:modules, lib_module.to_s)
+ lib_module
+ end
- project.save
+ # @param [Skippy::Library]
+ # @return [Array<Skippy::LibModule>]
+ def update(library)
+ raise Skippy::Project::ProjectNotSavedError unless project.exist?
+ installed = select { |mod| mod.library.name.casecmp(library.name).zero? }
+ installed.each { |mod| use(mod.name) }
+ installed
+ end
+ # @param [String] module_name
+ # @return [Skippy::LibModule]
+ def remove(module_name)
+ raise Skippy::Project::ProjectNotSavedError unless project.exist?
+ lib_module = project.libraries.find_module_or_fail(module_name)
+
+ target = vendor_path.join(lib_module.library.name, lib_module.path.basename)
+ support = vendor_path.join(lib_module.library.name, lib_module.basename)
+ target.delete if target.exist?
+ support.rmtree if support.directory?
+
+ @modules.delete_if { |mod| mod.name.casecmp(lib_module.name).zero? }
+
lib_module
end
# @return [Integer]
def length
to_a.length
end
- alias :size :length
+ alias size length
# @return [Pathname]
- def path
- project.path.join('src', project.namespace.to_underscore, 'vendor')
+ def vendor_path
+ project.extension_source.join(project.basename, 'vendor')
end
private
+ # @return [Array<Skippy::LibModule>]
+ def discover_modules
+ modules = []
+ project.libraries.each { |library|
+ library_vendor_path = vendor_path.join(library.name)
+ next unless library_vendor_path.directory?
+ library_vendor_path.each_child { |module_file|
+ next unless module_file.file?
+ next unless module_file.extname.casecmp('.rb').zero?
+ modules << Skippy::LibModule.new(library, module_file)
+ }
+ }
+ modules
+ end
+
+ # @param [Skippy::LibModule] lib_module
# @param [Pathname, String] source
# @param [Pathname, String] target
- def copy_module(source, target)
+ def copy_module(lib_module, source, target)
+ # Copy the main library file.
+ copy_file(lib_module, source, target)
+ # Copy optional support folder.
+ basename = source.basename('.*')
+ source_support_folder = source.parent.join(basename)
+ return unless source_support_folder.directory?
+ target_support_folder = target.parent.join(basename)
+ copy_directory(lib_module, source_support_folder, target_support_folder)
+ end
+
+ # @param [Skippy::LibModule] lib_module
+ # @param [Pathname, String] source
+ # @param [Pathname, String] target
+ def copy_directory(lib_module, source_path, target_path)
+ Dir.glob("#{source_path}/**/*") { |filename|
+ source = Pathname.new(filename)
+ next unless source.file?
+ relative_path = source.relative_path_from(source_path)
+ target = target_path.join(relative_path)
+ copy_file(lib_module, source, target)
+ }
+ end
+
+ # @param [Skippy::LibModule] lib_module
+ # @param [Pathname, String] source
+ # @param [Pathname, String] target
+ def copy_file(lib_module, source, target)
FileUtils.mkdir_p(target.parent)
- content = File.read(source)
- transform_module(content)
- File.write(target, content)
+ if source.extname.casecmp('.rb').zero?
+ content = File.read(source)
+ transform_require(lib_module, content)
+ transform_module(content)
+ File.write(target, content)
+ else
+ File.copy(source, target)
+ end
end
# Transform the module content with `SkippyLib` placeholder replaced with
# the project namespace.
#
# @param [String] content
# @return [String]
def transform_module(content)
content.gsub!('SkippyLib', project.namespace)
+ content
+ end
+
+ LIB_REQUIRE_PATTERN = %r{(\brequire ["'])(modules)(/[^"']*["'])}
+
+ # Transform the require statements to the target destination.
+ #
+ # @param [Skippy::LibModule] lib_module
+ # @param [String] content
+ # @return [String]
+ def transform_require(lib_module, content)
+ relative_path = vendor_path.relative_path_from(project.extension_source)
+ target_path = relative_path.join(lib_module.library.name)
+ content.gsub!(LIB_REQUIRE_PATTERN, "\\1#{target_path}\\3")
content
end
end