elm_install 0.3.1 → 1.0.0
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/.reek +4 -0
- data/.rspec +1 -0
- data/.rubocop.yml +4 -0
- data/Gemfile.lock +30 -25
- data/Rakefile +2 -2
- data/Readme.md +85 -23
- data/bin/elm-install +5 -2
- data/elm_install.gemspec +2 -0
- data/lib/elm_install.rb +18 -1
- data/lib/elm_install/base.rb +3 -46
- data/lib/elm_install/dependency.rb +37 -0
- data/lib/elm_install/directory_source.rb +66 -0
- data/lib/elm_install/ext.rb +23 -0
- data/lib/elm_install/git_source.rb +173 -0
- data/lib/elm_install/identifier.rb +133 -0
- data/lib/elm_install/installer.rb +38 -96
- data/lib/elm_install/populator.rb +54 -75
- data/lib/elm_install/repository.rb +82 -0
- data/lib/elm_install/resolver.rb +48 -118
- data/lib/elm_install/source.rb +18 -0
- data/lib/elm_install/types.rb +43 -0
- data/lib/elm_install/utils.rb +14 -20
- data/lib/elm_install/version.rb +1 -1
- data/package.json +1 -1
- data/packaging/Gemfile +1 -1
- data/packaging/Gemfile.lock +8 -4
- data/scripts/install.js +4 -4
- data/scripts/run.js +4 -4
- data/spec/directory_source_spec.rb +37 -0
- data/spec/{eml_install_spec.rb → elm_install_spec.rb} +6 -3
- data/spec/git_source_spec.rb +115 -0
- data/spec/identifer_spec.rb +53 -0
- data/spec/installer_spec.rb +57 -26
- data/spec/repository_spec.rb +44 -0
- data/spec/resolver_spec.rb +0 -73
- data/spec/spec_helper.rb +3 -1
- data/spec/utils_spec.rb +10 -15
- metadata +43 -17
- data/docs/How it works.md +0 -54
- data/lib/elm_install/cache.rb +0 -52
- data/lib/elm_install/elm_package.rb +0 -119
- data/lib/elm_install/git_resolver.rb +0 -129
- data/lib/elm_install/graph_builder.rb +0 -73
- data/spec/elm_package_spec.rb +0 -73
- data/spec/fixtures/cache.json +0 -8
- data/spec/fixtures/elm-package.json +0 -12
- data/spec/fixtures/invalid-elm-package.json +0 -6
- data/spec/fixtures/mismatched-elm-package.json +0 -9
- data/spec/fixtures/ref-cache.json +0 -4
- data/spec/git_resolver_spec.rb +0 -103
- data/spec/graph_builder_spec.rb +0 -36
- data/spec/populator_spec.rb +0 -44
@@ -1,129 +0,0 @@
|
|
1
|
-
require_relative './logger'
|
2
|
-
|
3
|
-
module ElmInstall
|
4
|
-
# This class if for cloning and fetching repositories based
|
5
|
-
# on a cache.
|
6
|
-
class GitResolver < Base
|
7
|
-
# Initializes a git resolver with the given options.
|
8
|
-
#
|
9
|
-
# @param options [Hash] The options
|
10
|
-
def initialize(options)
|
11
|
-
@file = 'ref-cache.json'
|
12
|
-
super options
|
13
|
-
@check_cache =
|
14
|
-
@cache.keys.each_with_object({}) { |key, memo| memo[key] = true }
|
15
|
-
end
|
16
|
-
|
17
|
-
# Returns the refs for a given url.
|
18
|
-
#
|
19
|
-
# @param url [String] the url
|
20
|
-
#
|
21
|
-
# @return [Hash] The refs
|
22
|
-
def refs(url)
|
23
|
-
self.class.refs(url)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Clears the cache
|
27
|
-
#
|
28
|
-
# @return [void]
|
29
|
-
def clear
|
30
|
-
@check_cache = {}
|
31
|
-
end
|
32
|
-
|
33
|
-
# Returns the refs for a given url.
|
34
|
-
#
|
35
|
-
# @param url [String] the url
|
36
|
-
#
|
37
|
-
# @return [Hash] The refs
|
38
|
-
def self.refs(url)
|
39
|
-
refs = Git.ls_remote url
|
40
|
-
refs.delete 'head'
|
41
|
-
JSON.parse(refs.to_json)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns if the given package (url) is in the cache.
|
45
|
-
#
|
46
|
-
# @param url [String] The url
|
47
|
-
#
|
48
|
-
# @return [Boolean] True if exists false if not
|
49
|
-
def package?(url)
|
50
|
-
@check_cache.key?(repository_path(url))
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the path of the repository for a given url.
|
54
|
-
#
|
55
|
-
# :reek:FeatureEnvy
|
56
|
-
#
|
57
|
-
# @param url [String] The url
|
58
|
-
#
|
59
|
-
# @return [String] The path
|
60
|
-
def repository_path(url)
|
61
|
-
uri = GitCloneUrl.parse(url)
|
62
|
-
File.join(directory, uri.host, uri.path)
|
63
|
-
end
|
64
|
-
|
65
|
-
# Returns a git repository object for the given url, cloning it
|
66
|
-
# if it does not exists.
|
67
|
-
#
|
68
|
-
# @param url [String] The url
|
69
|
-
#
|
70
|
-
# @return [Git::Base] The repository
|
71
|
-
def repository(url)
|
72
|
-
open(url) do |repo|
|
73
|
-
update_cache repo
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Updates a repository checking it's refs and fetching changes if needed.
|
78
|
-
#
|
79
|
-
# @param repo [Git::Base] The repository
|
80
|
-
#
|
81
|
-
# @return [void]
|
82
|
-
def update_cache(repo)
|
83
|
-
directory = File.dirname(repo.repo.path)
|
84
|
-
url = repo.remote.url
|
85
|
-
refs = refs(url)
|
86
|
-
|
87
|
-
unless HashDiff.diff(cache[directory], refs).empty?
|
88
|
-
Logger.arrow "Package: #{url.bold} is outdated, fetching changes..."
|
89
|
-
repo.fetch
|
90
|
-
end
|
91
|
-
|
92
|
-
@check_cache[directory] = true
|
93
|
-
cache[directory] = refs
|
94
|
-
end
|
95
|
-
|
96
|
-
# Opens a git repository cloning if it's not exists.
|
97
|
-
#
|
98
|
-
# @param url [String] The url
|
99
|
-
#
|
100
|
-
# @return [Git::Base] The repository
|
101
|
-
def open(url)
|
102
|
-
path = repository_path(url)
|
103
|
-
|
104
|
-
return clone url, path unless Dir.exist?(path)
|
105
|
-
|
106
|
-
repo = Git.open path
|
107
|
-
repo.reset_hard
|
108
|
-
|
109
|
-
yield repo unless @check_cache[path]
|
110
|
-
|
111
|
-
repo
|
112
|
-
end
|
113
|
-
|
114
|
-
# Clones the repostiry from the given url to the given path.
|
115
|
-
#
|
116
|
-
# @param url [String] The url
|
117
|
-
# @param path [String] The path
|
118
|
-
#
|
119
|
-
# @return [Git::Base] The repository
|
120
|
-
def clone(url, path)
|
121
|
-
Logger.arrow "Package: #{url.bold} not found in cache, cloning..."
|
122
|
-
FileUtils.mkdir_p path
|
123
|
-
repo = Git.clone(url, path)
|
124
|
-
@check_cache[path] = true
|
125
|
-
cache[path] = refs url
|
126
|
-
repo
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module ElmInstall
|
2
|
-
# This class is for building dependency graphs from a cache.
|
3
|
-
class GraphBuilder
|
4
|
-
# @return [Solve::Graph] The graph
|
5
|
-
attr_reader :graph
|
6
|
-
|
7
|
-
# Returns a graph from a cache and options.
|
8
|
-
#
|
9
|
-
# @param cache [Cache] The cache to generate the graph from.
|
10
|
-
# @param options [Hash] The options to use.
|
11
|
-
#
|
12
|
-
# @return [Solve::Graph] The graph
|
13
|
-
def self.graph_from_cache(cache, options = { verbose: false })
|
14
|
-
graph = new cache, options
|
15
|
-
graph.build
|
16
|
-
graph.graph
|
17
|
-
end
|
18
|
-
|
19
|
-
# Initialies a graph build with a cache and options.
|
20
|
-
#
|
21
|
-
# @param cache [Cache] The cache to generate the graph from.
|
22
|
-
# @param options [Hash] The options to use.
|
23
|
-
def initialize(cache, options = { verbose: false })
|
24
|
-
@graph = Solve::Graph.new
|
25
|
-
@options = options
|
26
|
-
@cache = cache
|
27
|
-
end
|
28
|
-
|
29
|
-
# Builds the graph.
|
30
|
-
#
|
31
|
-
# @return [void]
|
32
|
-
def build
|
33
|
-
@cache.each do |package, versions|
|
34
|
-
add_versions package, versions
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
# Adds the given package & version combinations to the graph.
|
41
|
-
def add_versions(package, versions)
|
42
|
-
versions.each do |version, dependencies|
|
43
|
-
add_version package, version, dependencies
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Adds the given package, version and dependency
|
48
|
-
# combinations to the graph.
|
49
|
-
def add_version(package, version, dependencies)
|
50
|
-
artifact = @graph.artifact(package, version)
|
51
|
-
|
52
|
-
dependencies.each do |dependency|
|
53
|
-
add_dependency artifact, *dependency
|
54
|
-
end
|
55
|
-
rescue
|
56
|
-
if @options[:verbose]
|
57
|
-
puts "WARNING: Could not add version #{version} to #{package}."
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Adds the given package version and single dependency to the
|
62
|
-
# graph.
|
63
|
-
def add_dependency(artifact, package, version)
|
64
|
-
artifact.depends package, version
|
65
|
-
rescue
|
66
|
-
if @options[:verbose]
|
67
|
-
puts "
|
68
|
-
WARNING: Could not add dependency #{package}-#{version} to #{artifact}
|
69
|
-
".strip
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
data/spec/elm_package_spec.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ElmInstall::ElmPackage do
|
4
|
-
subject { described_class }
|
5
|
-
|
6
|
-
let(:path) { 'spec/fixtures/elm-package.json' }
|
7
|
-
let(:invalid_path) { 'spec/fixtures/invalid-elm-package.json' }
|
8
|
-
let(:mismatch_path) { 'spec/fixtures/mismatched-elm-package.json' }
|
9
|
-
|
10
|
-
context 'package mismatch' do
|
11
|
-
subject { described_class.dependencies(mismatch_path, silent: false) }
|
12
|
-
|
13
|
-
it 'should exit' do
|
14
|
-
expect(ElmInstall::ElmPackage)
|
15
|
-
.to receive(:puts)
|
16
|
-
|
17
|
-
expect(Process).to receive(:exit)
|
18
|
-
subject
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'missing file' do
|
23
|
-
subject { described_class.dependencies('test', silent: false) }
|
24
|
-
|
25
|
-
it 'should exit' do
|
26
|
-
expect(ElmInstall::Logger)
|
27
|
-
.to receive(:arrow)
|
28
|
-
.with "Could not find file: #{'test'.bold}."
|
29
|
-
|
30
|
-
expect(Process).to receive(:exit)
|
31
|
-
|
32
|
-
expect { subject }.to raise_error(NoMethodError)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'invalid file' do
|
37
|
-
subject { described_class.dependencies(invalid_path, silent: false) }
|
38
|
-
|
39
|
-
it 'should exit' do
|
40
|
-
expect(ElmInstall::Logger)
|
41
|
-
.to receive(:arrow)
|
42
|
-
.with "Invalid JSON in file: #{invalid_path.bold}."
|
43
|
-
|
44
|
-
expect(Process).to receive(:exit)
|
45
|
-
|
46
|
-
expect { subject }.to raise_error(NoMethodError)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe '.transform_dependencies' do
|
51
|
-
subject { described_class.dependencies(path) }
|
52
|
-
|
53
|
-
it 'should return transformed dependencies' do
|
54
|
-
expect(subject)
|
55
|
-
.to eq(
|
56
|
-
'git@some-domain.com:test/repo' => 'development',
|
57
|
-
'https://github.com/base/core' => '2.0.0 <= v < 3.0.0'
|
58
|
-
)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '.transform_package' do
|
63
|
-
it 'should transform normal packages names to github ones' do
|
64
|
-
expect(subject.transform_package('test/repo'))
|
65
|
-
.to eq 'https://github.com/test/repo'
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'should return valid git urls' do
|
69
|
-
expect(subject.transform_package('git@github.com:test/repo'))
|
70
|
-
.to eq 'git@github.com:test/repo'
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
data/spec/fixtures/cache.json
DELETED
data/spec/git_resolver_spec.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ElmInstall::GitResolver do
|
4
|
-
subject { described_class.new directory: CACHE_DIRECTORY }
|
5
|
-
|
6
|
-
let(:uri) { 'git@github.com:test/repo' }
|
7
|
-
|
8
|
-
context 'With cache' do
|
9
|
-
subject { described_class.new directory: 'spec/fixtures' }
|
10
|
-
|
11
|
-
describe '#save' do
|
12
|
-
it 'should save cache' do
|
13
|
-
expect(File).to receive(:binwrite)
|
14
|
-
subject.save
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '#clear' do
|
19
|
-
it 'should clear the cache' do
|
20
|
-
expect do
|
21
|
-
subject.clear
|
22
|
-
end.to change {
|
23
|
-
subject.instance_variable_get('@check_cache').keys.count
|
24
|
-
}.from(2).to(0)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe '.repository' do
|
30
|
-
let(:refs) { {} }
|
31
|
-
let(:repo) { Git.init CACHE_DIRECTORY }
|
32
|
-
|
33
|
-
context 'with repository' do
|
34
|
-
let(:directory) { File.join CACHE_DIRECTORY, 'github.com/test/repo' }
|
35
|
-
|
36
|
-
before do
|
37
|
-
FileUtils.mkdir_p directory
|
38
|
-
Git.init directory
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'with cache' do
|
42
|
-
before do
|
43
|
-
subject.instance_variable_get('@check_cache')[directory] = {}
|
44
|
-
subject.cache[directory] = {}
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should return repository' do
|
48
|
-
repo = subject.repository uri
|
49
|
-
expect(File.dirname(repo.repo.path))
|
50
|
-
.to eq File.join(Dir.pwd, directory)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context 'without cache' do
|
55
|
-
before do
|
56
|
-
expect_any_instance_of(Git::Base)
|
57
|
-
.to receive(:fetch)
|
58
|
-
|
59
|
-
expect_any_instance_of(Git::Remote)
|
60
|
-
.to receive(:url)
|
61
|
-
.and_return uri.to_s
|
62
|
-
|
63
|
-
expect(Git)
|
64
|
-
.to receive(:ls_remote)
|
65
|
-
.and_return(refs)
|
66
|
-
|
67
|
-
expect(ElmInstall::Logger)
|
68
|
-
.to receive(:arrow)
|
69
|
-
.with "Package: #{'git@github.com:test/repo'.bold} is outdated, \
|
70
|
-
fetching changes...".gsub(/\s+/, ' ')
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should fetch refs and update cache' do
|
74
|
-
subject.repository uri
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'without repository' do
|
80
|
-
before do
|
81
|
-
expect(Git)
|
82
|
-
.to receive(:clone)
|
83
|
-
.and_return(repo)
|
84
|
-
|
85
|
-
expect(Git)
|
86
|
-
.to receive(:ls_remote)
|
87
|
-
.and_return(refs)
|
88
|
-
|
89
|
-
expect(ElmInstall::Logger)
|
90
|
-
.to receive(:arrow)
|
91
|
-
.with "Package: #{'git@github.com:test/repo'.bold} not found in \
|
92
|
-
cache, cloning...".gsub(/\s+/, ' ')
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'should clone a new repository' do
|
96
|
-
expect { subject.repository uri }
|
97
|
-
.to change { subject.cache.keys.count }
|
98
|
-
.from(0)
|
99
|
-
.to(1)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
data/spec/graph_builder_spec.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ElmInstall::GraphBuilder do
|
4
|
-
let(:cache) { ElmInstall::Cache.new(directory: 'spec/fixtures') }
|
5
|
-
|
6
|
-
subject { described_class.new cache, verbose: true }
|
7
|
-
|
8
|
-
describe '.graph_from_cache' do
|
9
|
-
it 'should generate a graph from cache' do
|
10
|
-
graph = described_class.graph_from_cache(cache)
|
11
|
-
names = graph.artifacts.map(&:name)
|
12
|
-
expect(names)
|
13
|
-
.to eq(['https://github.com/base/core',
|
14
|
-
'https://github.com/test/test'])
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '.add_version' do
|
19
|
-
it 'should rescue from errors' do
|
20
|
-
expect(subject).to receive(:puts)
|
21
|
-
|
22
|
-
subject.send(:add_version, 'test', 'asd', {})
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '.add_dependency' do
|
27
|
-
let(:artifact) { double :artifact }
|
28
|
-
|
29
|
-
it 'should rescue from errors' do
|
30
|
-
expect(subject).to receive(:puts)
|
31
|
-
expect(artifact).to receive(:depends).and_raise 'test'
|
32
|
-
|
33
|
-
subject.send(:add_dependency, artifact, 'asd', {})
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|