From bb892ad12337d70fae84ee2a76dbc97443b783e2 Mon Sep 17 00:00:00 2001 From: Jon Ruskin Date: Sat, 7 Mar 2020 12:01:36 -0700 Subject: [PATCH] expand source paths with glob patterns --- lib/licensed/configuration.rb | 24 ++++++++ test/configuration_test.rb | 111 ++++++++++++++++++++++++---------- 2 files changed, 104 insertions(+), 31 deletions(-) diff --git a/lib/licensed/configuration.rb b/lib/licensed/configuration.rb index f0cb38e1..7bf80c00 100644 --- a/lib/licensed/configuration.rb +++ b/lib/licensed/configuration.rb @@ -144,11 +144,35 @@ def self.load_from(path) def initialize(options = {}) apps = options.delete("apps") || [] apps << default_options.merge(options) if apps.empty? + apps = apps.flat_map { |app| self.class.expand_app_source_path(app) } @apps = apps.map { |app| AppConfiguration.new(app, options) } end private + def self.expand_app_source_path(app_config) + return app_config if app_config["source_path"].to_s.empty? + + source_path = File.expand_path(app_config["source_path"], AppConfiguration.root_for(app_config)) + expanded_source_paths = Dir.glob(source_path).select { |p| File.directory?(p) } + # return the original configuration if glob didn't result in multiple paths + return app_config if expanded_source_paths.size <= 1 + + # map the expanded paths to new application configurations + expanded_source_paths.map do |path| + config = app_config.merge("source_path" => path) + + # update configured values for name and cache_path for uniqueness. + # this is only needed when values are explicitly set, AppConfiguration + # will handle configurations that don't have these explicitly set + dir_name = File.basename(path) + config["name"] = "#{config["name"]}-#{dir_name}" if config["name"] + config["cache_path"] = File.join(config["cache_path"], dir_name) if config["cache_path"] + + config + end + end + # Find a default configuration file in the given directory. # File preference is given by the order of elements in DEFAULT_CONFIG_FILES # diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 2f4615dd..19bbadf5 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -2,12 +2,13 @@ require "test_helper" describe Licensed::Configuration do - let(:config) { Licensed::Configuration.new } - let(:app) { config.apps.first } + let(:options) { { } } + let(:config) { Licensed::Configuration.new(options) } let(:fixtures) { File.expand_path("../fixtures/config", __FILE__) } describe "load_from" do let(:config) { Licensed::Configuration.load_from(load_path) } + let(:app) { config.apps.first } describe "a relative directory path" do let(:load_path) { Pathname.new(fixtures).relative_path_from(Pathname.pwd) } @@ -64,49 +65,97 @@ end describe "apps" do + let(:apps) do + [ + { + "name" => "app1", + "override" => "override", + "cache_path" => "app1/vendor/licenses", + "source_path" => File.expand_path("../../", __FILE__) + }, + { + "name" => "app2", + "cache_path" => "app2/vendor/licenses", + "source_path" => File.expand_path("../../", __FILE__) + } + ] + end + let(:options) { { "apps" => apps } } + let(:config) { Licensed::Configuration.new(options) } + it "returns a default app if apps not specified in configuration" do + options.delete "apps" assert_equal 1, config.apps.size + app = config.apps.first assert_equal Pathname.pwd, app.source_path assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH), app.cache_path assert_equal File.basename(Dir.pwd), app["name"] end - describe "from configuration options" do - let(:apps) do - [ - { - "name" => "app1", - "override" => "override", - "cache_path" => "app1/vendor/licenses", - "source_path" => File.expand_path("../../", __FILE__) - }, - { - "name" => "app2", - "cache_path" => "app2/vendor/licenses", - "source_path" => File.expand_path("../../", __FILE__) - } - ] - end - let(:config) do - Licensed::Configuration.new("apps" => apps, - "override" => "default", - "default" => "default") + it "expands source_path patterns in default app" do + options.delete "apps" + options["source_path"] = File.expand_path("../fixtures/*", __FILE__) + expected_source_paths = Dir.glob(options["source_path"]).select { |p| File.directory?(p) } + expected_source_paths.each do |source_path| + app = config.apps.find { |app| app["source_path"] == source_path } + assert app + dir_name = File.basename(source_path) + assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, dir_name), + app.cache_path + assert_equal dir_name, app["name"] end + end + + it "returns configured apps" do + assert_equal 2, config.apps.size + assert_equal "app1", config.apps[0]["name"] + assert_equal "app2", config.apps[1]["name"] + end - it "returns apps from configuration" do - assert_equal 2, config.apps.size - assert_equal "app1", config.apps[0]["name"] - assert_equal "app2", config.apps[1]["name"] + it "includes default options" do + options["default"] = "default" + config.apps.each do |app| + assert_equal "default", app["default"] end + end - it "includes default options" do - assert_equal "default", config.apps[0]["default"] - assert_equal "default", config.apps[1]["default"] + it "can override default options" do + options["default"] = "default" + apps[0]["default"] = "override" + assert_equal "override", config.apps[0]["default"] + end + + it "expands patterns in configured apps" do + apps.clear + apps << { "source_path" => File.expand_path("../fixtures/*", __FILE__) } + expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) } + expected_source_paths.each do |source_path| + app = config.apps.find { |app| app["source_path"] == source_path } + assert app + dir_name = File.basename(source_path) + assert_equal app.root.join(Licensed::AppConfiguration::DEFAULT_CACHE_PATH, dir_name), + app.cache_path + assert_equal dir_name, app["name"] end + end - it "overrides default options" do - assert_equal "override", config.apps[0]["override"] + it "assigns uniqueness to explicitly configured values" do + cache_path = ".test_licenses" + name = "test" + apps.clear + apps << { + "source_path" => File.expand_path("../fixtures/*", __FILE__), + "cache_path" => cache_path, + "name" => name + } + expected_source_paths = Dir.glob(apps[0]["source_path"]).select { |p| File.directory?(p) } + expected_source_paths.each do |source_path| + app = config.apps.find { |app| app["source_path"] == source_path } + assert app + dir_name = File.basename(source_path) + assert_equal app.root.join(cache_path, dir_name), app.cache_path + assert_equal "#{name}-#{dir_name}", app["name"] end end end