natives 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +2 -3
- data/Gemfile.lock +12 -53
- data/README.md +126 -29
- data/Rakefile +4 -5
- data/VERSION +1 -1
- data/bin/natives +1 -0
- data/catalogs/rubygems.yaml +50 -0
- data/lib/natives/apps/detect.rb +21 -0
- data/lib/natives/apps/list.rb +39 -0
- data/lib/natives/apps.rb +2 -0
- data/lib/natives/catalog/loader.rb +30 -0
- data/lib/natives/catalog/merger.rb +26 -0
- data/lib/natives/catalog/selector.rb +79 -0
- data/lib/natives/catalog/validator.rb +18 -0
- data/lib/natives/catalog.rb +56 -0
- data/lib/natives/cli.rb +27 -42
- data/lib/natives/gemfile_viewer.rb +19 -16
- data/lib/natives/host_detection/package_provider.rb +83 -0
- data/lib/natives/host_detection/platform.rb +34 -0
- data/lib/natives/host_detection.rb +25 -0
- data/lib/natives.rb +1 -0
- data/spec/fixtures/dir_with_matching_files/invalid1.yml +9 -0
- data/spec/fixtures/dir_with_matching_files/not_matching.json +0 -0
- data/spec/fixtures/dir_with_matching_files/valid1.yaml +21 -0
- data/spec/fixtures/dir_with_matching_files/valid2.yml +9 -0
- data/spec/fixtures/dir_without_matching_file/not_matching.json +0 -0
- data/spec/natives/apps/detect_spec.rb +26 -0
- data/spec/natives/apps/list_spec.rb +58 -0
- data/spec/natives/catalog/loader_spec.rb +101 -0
- data/spec/natives/catalog/merger_spec.rb +60 -0
- data/spec/natives/catalog/selector_spec.rb +124 -0
- data/spec/natives/catalog/validator_spec.rb +44 -0
- data/spec/natives/catalog_spec.rb +133 -0
- data/spec/natives/gemfile_viewer_spec.rb +3 -3
- data/spec/natives/host_detection/package_provider_spec.rb +33 -0
- data/spec/natives/host_detection/platform_spec.rb +21 -0
- data/spec/natives/host_detection_spec.rb +45 -0
- data/spec/spec_helper.rb +17 -2
- metadata +44 -66
- data/chef/.kitchen.yml +0 -27
- data/chef/Berksfile +0 -4
- data/chef/Berksfile.lock +0 -10
- data/chef/cookbooks/natives/Berksfile +0 -3
- data/chef/cookbooks/natives/Gemfile +0 -5
- data/chef/cookbooks/natives/LICENSE +0 -3
- data/chef/cookbooks/natives/README.md +0 -13
- data/chef/cookbooks/natives/chefignore +0 -96
- data/chef/cookbooks/natives/libraries/natives_recipe_helper.rb +0 -37
- data/chef/cookbooks/natives/metadata.rb +0 -9
- data/chef/cookbooks/natives/recipes/default.rb +0 -31
- data/chef/solo.rb +0 -17
- data/chef/vendored-cookbooks/apt/CHANGELOG.md +0 -144
- data/chef/vendored-cookbooks/apt/README.md +0 -247
- data/chef/vendored-cookbooks/apt/attributes/default.rb +0 -27
- data/chef/vendored-cookbooks/apt/files/default/apt-proxy-v2.conf +0 -50
- data/chef/vendored-cookbooks/apt/libraries/helpers.rb +0 -47
- data/chef/vendored-cookbooks/apt/libraries/network.rb +0 -33
- data/chef/vendored-cookbooks/apt/metadata.json +0 -54
- data/chef/vendored-cookbooks/apt/metadata.rb +0 -34
- data/chef/vendored-cookbooks/apt/providers/preference.rb +0 -61
- data/chef/vendored-cookbooks/apt/providers/repository.rb +0 -141
- data/chef/vendored-cookbooks/apt/recipes/cacher-client.rb +0 -81
- data/chef/vendored-cookbooks/apt/recipes/cacher-ng.rb +0 -43
- data/chef/vendored-cookbooks/apt/recipes/default.rb +0 -83
- data/chef/vendored-cookbooks/apt/resources/preference.rb +0 -30
- data/chef/vendored-cookbooks/apt/resources/repository.rb +0 -41
- data/chef/vendored-cookbooks/apt/templates/debian-6.0/acng.conf.erb +0 -173
- data/chef/vendored-cookbooks/apt/templates/default/01proxy.erb +0 -5
- data/chef/vendored-cookbooks/apt/templates/default/acng.conf.erb +0 -275
- data/chef/vendored-cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +0 -269
- data/chef/vendored-cookbooks/homebrew/CHANGELOG.md +0 -36
- data/chef/vendored-cookbooks/homebrew/README.md +0 -110
- data/chef/vendored-cookbooks/homebrew/attributes/default.rb +0 -22
- data/chef/vendored-cookbooks/homebrew/libraries/homebrew_mixin.rb +0 -53
- data/chef/vendored-cookbooks/homebrew/libraries/homebrew_package.rb +0 -104
- data/chef/vendored-cookbooks/homebrew/metadata.json +0 -32
- data/chef/vendored-cookbooks/homebrew/metadata.rb +0 -10
- data/chef/vendored-cookbooks/homebrew/providers/tap.rb +0 -48
- data/chef/vendored-cookbooks/homebrew/recipes/default.rb +0 -46
- data/chef/vendored-cookbooks/homebrew/resources/tap.rb +0 -35
- data/lib/natives/app.rb +0 -71
- data/natives.gemspec +0 -125
- data/spec/natives/app_spec.rb +0 -153
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'natives/catalog/loader'
|
2
|
+
require 'natives/catalog/selector'
|
3
|
+
|
4
|
+
module Natives
|
5
|
+
class Catalog
|
6
|
+
|
7
|
+
CATALOG_PATH_IN_GEM = File.absolute_path(File.join(
|
8
|
+
File.dirname(__FILE__), '..', '..', 'catalogs'))
|
9
|
+
|
10
|
+
WORKING_DIR_CATALOG_DIRNAME = 'natives-catalogs'
|
11
|
+
|
12
|
+
attr_reader :platform, :platform_version, :package_provider, :name
|
13
|
+
|
14
|
+
def initialize(catalog_name,
|
15
|
+
platform, platform_version,
|
16
|
+
package_provider,
|
17
|
+
opts={})
|
18
|
+
|
19
|
+
@name = catalog_name.to_s
|
20
|
+
@platform = platform.to_s
|
21
|
+
@platform_version = platform_version.to_s
|
22
|
+
@package_provider = package_provider.to_s
|
23
|
+
|
24
|
+
@loader = opts.fetch(:loader, Loader.new)
|
25
|
+
@working_dir = opts.fetch(:working_dir, Dir.pwd)
|
26
|
+
|
27
|
+
reload
|
28
|
+
end
|
29
|
+
|
30
|
+
def reload
|
31
|
+
@catalogs = @loader.load_from_paths(catalog_paths)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_hash
|
35
|
+
@catalogs.fetch(self.name, {})
|
36
|
+
end
|
37
|
+
|
38
|
+
def native_packages_for(*entry_names)
|
39
|
+
packages = Array(entry_names).flatten.map do |entry_name|
|
40
|
+
Selector.new(self.to_hash.fetch(entry_name, {})).
|
41
|
+
value_for(@platform, @platform_version, @package_provider)
|
42
|
+
end
|
43
|
+
packages.flatten.compact
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def catalog_paths
|
49
|
+
[
|
50
|
+
CATALOG_PATH_IN_GEM,
|
51
|
+
File.absolute_path(File.join(@working_dir, WORKING_DIR_CATALOG_DIRNAME))
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
data/lib/natives/cli.rb
CHANGED
@@ -1,60 +1,45 @@
|
|
1
1
|
require 'thor'
|
2
|
-
require 'natives/
|
3
|
-
require 'natives/gemfile_viewer'
|
2
|
+
require 'natives/apps'
|
4
3
|
|
5
4
|
module Natives
|
6
5
|
class Cli < Thor
|
7
|
-
default_task :install
|
8
6
|
|
9
|
-
desc '
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
desc 'install [ENTRY1 ENTRY2 ..]',
|
15
|
-
'install native packages required by the catalog entries'
|
16
|
-
|
17
|
-
method_option :catalog, default: 'rubygems',
|
18
|
-
aliases: '-c',
|
7
|
+
desc 'list [ENTRY1 ENTRY2 ..]',
|
8
|
+
'list native packages required by the catalog entries'
|
9
|
+
method_option :catalog, default: 'rubygems', aliases: '-c',
|
19
10
|
desc: 'use this catalog'
|
20
11
|
method_option :gemfile, default: 'Gemfile',
|
21
12
|
desc: 'use gems in the gemfile as the catalog entries'
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
desc: "run without actually installing native packages"
|
31
|
-
|
32
|
-
def install(*packages)
|
33
|
-
catalog = options[:catalog]
|
34
|
-
configs = {
|
35
|
-
update_provider: options['update-provider'],
|
36
|
-
test_run: options['test-run']
|
37
|
-
}
|
38
|
-
if catalog == 'rubygems' && packages.empty?
|
39
|
-
packages = packages_in_gemfile(options[:gemfile])
|
13
|
+
def list(*entry_names)
|
14
|
+
app = Apps::List.new
|
15
|
+
|
16
|
+
catalog_name = options[:catalog]
|
17
|
+
if catalog_name == 'rubygems' && entry_names.empty?
|
18
|
+
packages = app.natives_for_gemfile(options[:gemfile])
|
19
|
+
else
|
20
|
+
packages = app.natives_for(catalog_name, entry_names)
|
40
21
|
end
|
41
22
|
|
42
|
-
puts
|
43
|
-
puts "entries: #{packages.inspect}"
|
44
|
-
puts "configs: #{configs}"
|
45
|
-
puts ""
|
46
|
-
|
47
|
-
Natives::App.new.install(catalog, packages, configs)
|
48
|
-
|
23
|
+
puts packages
|
49
24
|
rescue => ex
|
50
25
|
$stderr.puts ex.message
|
51
26
|
end
|
52
27
|
|
53
|
-
|
54
|
-
|
55
|
-
def
|
56
|
-
|
28
|
+
desc 'detect',
|
29
|
+
'detect and print platform and package provider information'
|
30
|
+
def detect
|
31
|
+
app = Apps::Detect.new
|
32
|
+
puts app.detection_info
|
57
33
|
end
|
58
34
|
|
35
|
+
desc 'version',
|
36
|
+
'print version information'
|
37
|
+
def version
|
38
|
+
version_file = File.expand_path(File.join(
|
39
|
+
File.dirname(__FILE__), '..', '..', 'VERSION'))
|
40
|
+
|
41
|
+
puts IO.read(version_file)
|
42
|
+
end
|
59
43
|
end
|
44
|
+
|
60
45
|
end
|
@@ -1,29 +1,32 @@
|
|
1
|
-
|
2
1
|
module Natives
|
3
2
|
class GemfileViewer
|
4
3
|
def initialize(gemfile_path)
|
5
4
|
@gemfile_path = gemfile_path
|
6
5
|
end
|
7
6
|
|
8
|
-
def
|
9
|
-
|
10
|
-
# After several trial-and-error, this works:
|
11
|
-
# 1. cd to the dir containing the gemfile
|
12
|
-
# 2. after that run bundle show
|
13
|
-
gemfile_dir = File.expand_path(File.dirname(@gemfile_path))
|
14
|
-
gemfile_name = File.basename(@gemfile_path)
|
15
|
-
output = %x{cd '#{gemfile_dir}' && BUNDLE_GEMFILE=#{gemfile_name} bundle show 2>&1}
|
16
|
-
success = ($?.exitstatus == 0)
|
17
|
-
unless success
|
18
|
-
raise "Failed to list packages in Gemfile: #{@gemfile_path.inspect}\nReason:\n#{output}"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
extract_packages(output)
|
7
|
+
def gem_names
|
8
|
+
extract_gem_names(bundle_list(@gemfile_path))
|
22
9
|
end
|
23
10
|
|
24
11
|
protected
|
25
12
|
|
26
|
-
def
|
13
|
+
def bundle_list(gemfile_path)
|
14
|
+
# after trial-and-error, these steps work best:
|
15
|
+
# 1. cd to dir containing the gemfile
|
16
|
+
# 2. bundle list
|
17
|
+
dir = File.expand_path(File.dirname(@gemfile_path))
|
18
|
+
filename = File.basename(@gemfile_path)
|
19
|
+
output = %x{cd '#{dir}' && BUNDLE_GEMFILE=#{filename} bundle list 2>&1}
|
20
|
+
successful_run = ($?.exitstatus == 0)
|
21
|
+
|
22
|
+
unless successful_run
|
23
|
+
raise "Cannot list gems in gemfile #{@gemfile_path.inspect}: #{output}"
|
24
|
+
end
|
25
|
+
|
26
|
+
output
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_gem_names(output)
|
27
30
|
lines = output.split("\n")
|
28
31
|
lines.shift # remove first line
|
29
32
|
lines.map do |line|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Natives
|
2
|
+
class HostDetection
|
3
|
+
class PackageProvider
|
4
|
+
COMMANDS = {
|
5
|
+
'aix' => 'installp',
|
6
|
+
'yum' => 'yum',
|
7
|
+
'packman' => 'packman',
|
8
|
+
'apt' => 'apt-get',
|
9
|
+
'feebsd' => 'pkg_add',
|
10
|
+
'portage' => 'emerge',
|
11
|
+
'homebrew' => 'brew',
|
12
|
+
'macports' => 'port',
|
13
|
+
'solaris' => 'pkg_add',
|
14
|
+
'ips' => 'pkg',
|
15
|
+
'zypper' => 'zypper',
|
16
|
+
'smartos' => 'pkgin'
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
PROVIDERS = {
|
20
|
+
'aix' => 'aix',
|
21
|
+
'amazon' => 'yum',
|
22
|
+
'arch' => 'pacman',
|
23
|
+
'centos' => 'yum',
|
24
|
+
'debian' => 'apt',
|
25
|
+
'fedora' => 'yum',
|
26
|
+
'freebsd' => 'freebsd',
|
27
|
+
'gcel' => 'apt',
|
28
|
+
'gentoo' => 'portage',
|
29
|
+
'linaro' => 'apt',
|
30
|
+
'linuxmint' => 'apt',
|
31
|
+
'mac_os_x' => ['homebrew', 'macports'],
|
32
|
+
'mac_os_x_server' => 'macports',
|
33
|
+
'nexentacore' => 'solaris',
|
34
|
+
'omnios' => 'ips',
|
35
|
+
'openindiana' => 'ips',
|
36
|
+
'opensolaris' => 'ips',
|
37
|
+
'opensuse' => 'zypper',
|
38
|
+
'oracle' => 'yum',
|
39
|
+
'raspbian' => 'apt',
|
40
|
+
'redhat' => 'yum',
|
41
|
+
'scientific' => 'yum',
|
42
|
+
'smartos' => 'smartos',
|
43
|
+
'solaris2' => 'ips',
|
44
|
+
'suse' => 'zypper',
|
45
|
+
'ubuntu' => 'apt',
|
46
|
+
'xcp' => 'yum',
|
47
|
+
'xenserver' => 'yum'
|
48
|
+
}.freeze
|
49
|
+
|
50
|
+
def initialize(platform)
|
51
|
+
@platform = platform
|
52
|
+
end
|
53
|
+
|
54
|
+
def name
|
55
|
+
providers = Array(PROVIDERS[@platform.name])
|
56
|
+
return providers.first if providers.count < 2
|
57
|
+
|
58
|
+
providers.find do |provider|
|
59
|
+
which(COMMANDS[provider]) != nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
# copied from Chef cookbook 'apt'
|
66
|
+
# source: apt/libraries/helpers.rb
|
67
|
+
def which(cmd)
|
68
|
+
paths = (
|
69
|
+
ENV['PATH'].split(::File::PATH_SEPARATOR) +
|
70
|
+
%w(/bin /usr/bin /sbin /usr/sbin /opt/local/bin)
|
71
|
+
)
|
72
|
+
|
73
|
+
paths.each do |path|
|
74
|
+
possible = File.join(path, cmd)
|
75
|
+
return possible if File.executable?(possible)
|
76
|
+
end
|
77
|
+
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'ohai'
|
2
|
+
|
3
|
+
module Natives
|
4
|
+
class HostDetection
|
5
|
+
class Platform
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@ohai = build_ohai
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
ohai_hash[:platform]
|
13
|
+
end
|
14
|
+
|
15
|
+
def version
|
16
|
+
ohai_hash[:platform_version]
|
17
|
+
end
|
18
|
+
|
19
|
+
def ohai_hash
|
20
|
+
@ohai
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def build_ohai
|
26
|
+
ohai = Ohai::System.new
|
27
|
+
ohai.require_plugin 'os'
|
28
|
+
ohai.require_plugin 'platform'
|
29
|
+
ohai
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'natives/host_detection/platform'
|
2
|
+
require 'natives/host_detection/package_provider'
|
3
|
+
|
4
|
+
module Natives
|
5
|
+
class HostDetection
|
6
|
+
|
7
|
+
def initialize(opts={})
|
8
|
+
@detect_platform = opts.fetch(:detect_platform) { Platform.new }
|
9
|
+
@detect_package_provider = opts.fetch(:detect_package_provider) {
|
10
|
+
PackageProvider.new(@detect_platform) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def platform
|
14
|
+
@detect_platform.name
|
15
|
+
end
|
16
|
+
|
17
|
+
def platform_version
|
18
|
+
@detect_platform.version
|
19
|
+
end
|
20
|
+
|
21
|
+
def package_provider
|
22
|
+
@detect_package_provider.name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/natives.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require 'natives/apps'
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
rubygems:
|
2
|
+
capybara-webkit:
|
3
|
+
mac_os_x/macports:
|
4
|
+
default:
|
5
|
+
- qt4-mac-devel
|
6
|
+
mac_os_x/homebrew:
|
7
|
+
default:
|
8
|
+
- qt
|
9
|
+
ubuntu/apt:
|
10
|
+
default:
|
11
|
+
- libqtwebkit-dev
|
12
|
+
[10.04,10.04.1,10.04.2,10.04.3,10.04.4]:
|
13
|
+
- libqt4-dev
|
14
|
+
rmagick:
|
15
|
+
mac_os_x/homebrew:
|
16
|
+
default:
|
17
|
+
- imagemagick
|
18
|
+
ubuntu/apt:
|
19
|
+
default:
|
20
|
+
- imagemagick
|
21
|
+
- libmagick9-dev
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'natives/apps/detect'
|
3
|
+
|
4
|
+
describe Natives::Apps::Detect do
|
5
|
+
it "detects host's platform and package provider info" do
|
6
|
+
app = Natives::Apps::Detect.new
|
7
|
+
|
8
|
+
host_detection = double()
|
9
|
+
host_detection.stub(platform: 'ubuntu')
|
10
|
+
host_detection.stub(platform_version: '12.3.2')
|
11
|
+
host_detection.stub(package_provider: 'apt')
|
12
|
+
app.should_receive(:new_host_detection).
|
13
|
+
and_return(host_detection)
|
14
|
+
|
15
|
+
expect(app.detection_info).to eq([
|
16
|
+
'platform: ubuntu',
|
17
|
+
'platform_version: 12.3.2',
|
18
|
+
'package_provider: apt'
|
19
|
+
].join("\n"))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uses HostDetection" do
|
23
|
+
app = Natives::Apps::Detect.new
|
24
|
+
expect(app.new_host_detection).to be_kind_of Natives::HostDetection
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'natives/apps/list'
|
3
|
+
|
4
|
+
describe Natives::Apps::List do
|
5
|
+
context "given catalog entry names" do
|
6
|
+
it "lists native packages" do
|
7
|
+
catalog_name = 'rubygems'
|
8
|
+
entry_names = %w(sqlite3 capybara-webkit nokogiri curb)
|
9
|
+
|
10
|
+
catalog = double()
|
11
|
+
catalog.should_receive(:native_packages_for).
|
12
|
+
with(entry_names).
|
13
|
+
and_return(%w(foo bar spam))
|
14
|
+
|
15
|
+
host_detection = double()
|
16
|
+
host_detection.should_receive(:platform)
|
17
|
+
host_detection.should_receive(:platform_version)
|
18
|
+
host_detection.should_receive(:package_provider)
|
19
|
+
|
20
|
+
list = Natives::Apps::List.new
|
21
|
+
list.stub(new_catalog: catalog)
|
22
|
+
list.stub(new_host_detection: host_detection)
|
23
|
+
|
24
|
+
packages = list.natives_for(catalog_name, entry_names)
|
25
|
+
|
26
|
+
expect(packages).to eq %w(foo bar spam)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "given a gemfile path" do
|
31
|
+
it "lists native packages" do
|
32
|
+
gemfile_path = 'path/to/gemfile'
|
33
|
+
list = Natives::Apps::List.new
|
34
|
+
|
35
|
+
gemfile_viewer = double()
|
36
|
+
gemfile_viewer.should_receive(:gem_names).
|
37
|
+
and_return(%w(gem1 gem2 gem3))
|
38
|
+
|
39
|
+
host_detection = double()
|
40
|
+
host_detection.should_receive(:platform)
|
41
|
+
host_detection.should_receive(:platform_version)
|
42
|
+
host_detection.should_receive(:package_provider)
|
43
|
+
|
44
|
+
catalog = double()
|
45
|
+
catalog.should_receive(:native_packages_for).
|
46
|
+
with(%w(gem1 gem2 gem3)).
|
47
|
+
and_return(%w(foo bar spam))
|
48
|
+
|
49
|
+
list.stub(new_gemfile_viewer: gemfile_viewer)
|
50
|
+
list.stub(new_catalog: catalog)
|
51
|
+
list.stub(new_host_detection: host_detection)
|
52
|
+
|
53
|
+
packages= list.natives_for_gemfile(gemfile_path)
|
54
|
+
|
55
|
+
expect(packages).to eq %w(foo bar spam)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'natives/catalog/loader'
|
3
|
+
|
4
|
+
describe Natives::Catalog::Loader do
|
5
|
+
describe "#load_from_paths" do
|
6
|
+
let(:loader) { Natives::Catalog::Loader.new }
|
7
|
+
|
8
|
+
it "loads files in catalog paths, in the order of given paths and sorted filenames" do
|
9
|
+
files = {
|
10
|
+
'/to/path1' => ['/to/path1/file1.yaml'],
|
11
|
+
'/to/path2' => ['/to/path2/file2.yaml', '/to/path2/file1.yaml'],
|
12
|
+
'/to/path3' => ['/to/path3/file2.yaml', '/to/path3/file1.yaml', '/to/path3/file3.yaml']
|
13
|
+
}
|
14
|
+
catalog_hashes = {
|
15
|
+
'/to/path1/file1.yaml' => {"rubygems" => { "p" => "p1f1", "p1" => "p1f1", "p1f1" => "" } },
|
16
|
+
'/to/path2/file1.yaml' => {"rubygems" => { "p" => "p2f1", "p2" => "p2f1", "p2f1" => "" } },
|
17
|
+
'/to/path2/file2.yaml' => {"rubygems" => { "p" => "p2f2", "p2" => "p2f2", "p2f2" => "" } },
|
18
|
+
'/to/path3/file1.yaml' => {"rubygems" => { "p" => "p3f1", "p3" => "p3f1", "p3f1" => "" } },
|
19
|
+
'/to/path3/file2.yaml' => {"rubygems" => { "p" => "p3f2", "p3" => "p3f2", "p3f2" => "" } },
|
20
|
+
'/to/path3/file3.yaml' => {"rubygems" => { "p" => "p3f3", "p3" => "p3f3", "p3f3" => "" } }
|
21
|
+
}
|
22
|
+
loader.stub(:yaml_files_in_path) { |path| files[path] }
|
23
|
+
loader.stub(:load_yaml_file) {|file| catalog_hashes[file] }
|
24
|
+
|
25
|
+
given_catalog_paths = ['/to/path3', '/to/path1', '/to/path2']
|
26
|
+
expected_hash = {
|
27
|
+
"rubygems" => {
|
28
|
+
"p" => "p2f2",
|
29
|
+
"p1" => "p1f1",
|
30
|
+
"p2" => "p2f2",
|
31
|
+
"p3" => "p3f3",
|
32
|
+
"p1f1" => "",
|
33
|
+
"p2f1" => "",
|
34
|
+
"p2f2" => "",
|
35
|
+
"p3f1" => "",
|
36
|
+
"p3f2" => "",
|
37
|
+
"p3f3" => ""
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
actual_hash = loader.load_from_paths(given_catalog_paths)
|
42
|
+
expect(actual_hash).to include(expected_hash)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#yaml_files_in_path" do
|
48
|
+
let(:loader) { Natives::Catalog::Loader.new }
|
49
|
+
|
50
|
+
it "returns a list of *.yml *.yaml filenames in the given path" do
|
51
|
+
path = File.join(RSpec.configuration.fixture_path, 'dir_with_matching_files')
|
52
|
+
filenames = loader.yaml_files_in_path(path)
|
53
|
+
expected_filenames = [
|
54
|
+
File.join(path, 'invalid1.yml'),
|
55
|
+
File.join(path, 'valid1.yaml'),
|
56
|
+
File.join(path, 'valid2.yml')
|
57
|
+
]
|
58
|
+
expect(filenames.sort).to eq(expected_filenames.sort)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns empty list if there is no matching file in the given path" do
|
62
|
+
path = File.join(RSpec.configuration.fixture_path, 'dir_without_matching_file')
|
63
|
+
filenames = loader.yaml_files_in_path(path)
|
64
|
+
expect(filenames).to eq([])
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns empty list if the given path does not exist" do
|
68
|
+
path = File.join(RSpec.configuration.fixture_path, 'dir_not_exists')
|
69
|
+
filenames = loader.yaml_files_in_path(path)
|
70
|
+
expect(filenames).to eq([])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#load_yaml_file" do
|
75
|
+
let(:loader) { Natives::Catalog::Loader.new }
|
76
|
+
|
77
|
+
it "loads the given file as YAML" do
|
78
|
+
valid_file = File.join(RSpec.configuration.fixture_path,
|
79
|
+
'dir_with_matching_files', 'valid1.yaml')
|
80
|
+
|
81
|
+
hash = loader.load_yaml_file(valid_file)
|
82
|
+
|
83
|
+
expect(hash).to include("rubygems")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "raises error when the given file contains invalid YAML" do
|
87
|
+
valid_file = File.join(RSpec.configuration.fixture_path,
|
88
|
+
'dir_with_matching_files', 'invalid1.yml')
|
89
|
+
|
90
|
+
expect {
|
91
|
+
loader.load_yaml_file(valid_file)
|
92
|
+
}.to raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
it "raises error when the given file does not exist" do
|
96
|
+
expect {
|
97
|
+
loader.load_yaml_file("file_not_exists.yaml")
|
98
|
+
}.to raise_error
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'natives/catalog/merger'
|
3
|
+
|
4
|
+
describe Natives::Catalog::Merger do
|
5
|
+
|
6
|
+
describe "#merge_catalog!" do
|
7
|
+
let(:merger) { Natives::Catalog::Merger.new }
|
8
|
+
|
9
|
+
it "validates both master_hash and hash_to_merge" do
|
10
|
+
master_hash = {}
|
11
|
+
hash_to_merge = {"rubygems" => {}}
|
12
|
+
validator = double("Natives::Catalog::Validator")
|
13
|
+
merger = Natives::Catalog::Merger.new(validator: validator)
|
14
|
+
|
15
|
+
validator.should_receive(:ensure_valid_catalog_groups).with(master_hash)
|
16
|
+
validator.should_receive(:ensure_valid_catalog_groups).with(hash_to_merge)
|
17
|
+
|
18
|
+
merger.merge_catalog!(master_hash, hash_to_merge)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns master_hash" do
|
22
|
+
master_hash = {}
|
23
|
+
expect(merger.merge_catalog!(master_hash, {})).to equal(master_hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "adds new catalog group into master_hash" do
|
27
|
+
master_hash = {}
|
28
|
+
hash_to_merge = {"rubygems" => {}}
|
29
|
+
|
30
|
+
merger.merge_catalog!(master_hash, hash_to_merge)
|
31
|
+
|
32
|
+
expect(master_hash).to include("rubygems" => {})
|
33
|
+
end
|
34
|
+
|
35
|
+
it "adds new entries into existing catalog group" do
|
36
|
+
master_hash = {"rubygems" => { "curb" => {} }}
|
37
|
+
hash_to_merge = {"rubygems" => { "nokogiri" => {} }}
|
38
|
+
|
39
|
+
merger.merge_catalog!(master_hash, hash_to_merge)
|
40
|
+
|
41
|
+
expect(master_hash).to include(
|
42
|
+
"rubygems" => {"curb" => {}, "nokogiri" => {}})
|
43
|
+
end
|
44
|
+
|
45
|
+
it "replaces existing entries in existing catalog group" do
|
46
|
+
master_hash = {"rubygems" => {
|
47
|
+
"webkit-capybara" => {},
|
48
|
+
"curb" => {} }}
|
49
|
+
hash_to_merge = {"rubygems" => {
|
50
|
+
"curb" => {"foo" => "bar"}, "nokogiri" => {} }}
|
51
|
+
|
52
|
+
merger.merge_catalog!(master_hash, hash_to_merge)
|
53
|
+
|
54
|
+
expect(master_hash).to include(
|
55
|
+
"rubygems" => {
|
56
|
+
"webkit-capybara" => {},
|
57
|
+
"curb" => {"foo" => "bar"}, "nokogiri" => {}})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|