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,100 +1,79 @@
|
|
1
1
|
module ElmInstall
|
2
|
-
#
|
3
|
-
class Populator
|
4
|
-
|
2
|
+
# Populator for 'elm-stuff' directory
|
3
|
+
class Populator < Base
|
4
|
+
Contract ArrayOf[Dependency] => Populator
|
5
|
+
# Initializes a new populator
|
5
6
|
#
|
6
|
-
# @param
|
7
|
-
def initialize(git_resolver)
|
8
|
-
@git_resolver = git_resolver
|
9
|
-
end
|
10
|
-
|
11
|
-
# Populates `elm-stuff` from the given solution.
|
12
|
-
#
|
13
|
-
# @param solution [Hash] The solution.
|
14
|
-
#
|
15
|
-
# @return [void]
|
16
|
-
def populate(solution)
|
17
|
-
solution.each do |package, version|
|
18
|
-
resolve_package package, version
|
19
|
-
end
|
20
|
-
|
21
|
-
write_exact_dependencies(solution)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Resolves and copies a package and it's version to `elm-stuff/packages`
|
25
|
-
# directory.
|
26
|
-
#
|
27
|
-
# :reek:TooManyStatements { max_statements: 9 }
|
7
|
+
# @param dependencies [Array] The dependencies to populate
|
28
8
|
#
|
29
|
-
# @
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def resolve_package(package, version_str)
|
34
|
-
version, ref = self.class.version_and_ref(version_str)
|
35
|
-
|
36
|
-
package_name, package_path = Utils.package_version_path package, version
|
37
|
-
|
38
|
-
@git_resolver.repository(package).checkout(ref)
|
39
|
-
|
40
|
-
Logger.dot "#{package_name.bold} - #{version.bold} (#{ref})"
|
41
|
-
|
42
|
-
FileUtils.rm_rf(package_path) if Dir.exist?(package_path)
|
43
|
-
|
44
|
-
copy_package package, package_path
|
9
|
+
# @return Populator The populator instance
|
10
|
+
def initialize(dependencies)
|
11
|
+
@dependencies = dependencies
|
12
|
+
self
|
45
13
|
end
|
46
14
|
|
47
|
-
|
15
|
+
Contract None => NilClass
|
16
|
+
# Populates 'elm-stuff' directory and writes
|
17
|
+
# 'elm-stuff/exact-dependencies.json'.
|
48
18
|
#
|
49
|
-
# @
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def copy_package(package, package_path)
|
54
|
-
repository_path = File.join(@git_resolver.repository_path(package), '.')
|
55
|
-
|
56
|
-
FileUtils.mkdir_p(package_path)
|
57
|
-
FileUtils.cp_r(repository_path, package_path)
|
58
|
-
FileUtils.rm_rf(File.join(package_path, '.git'))
|
19
|
+
# @return nil
|
20
|
+
def populate
|
21
|
+
copy_dependencies
|
22
|
+
write_exact_dependencies
|
59
23
|
end
|
60
24
|
|
61
|
-
|
62
|
-
#
|
63
|
-
# @param solution [Hash] The solution
|
25
|
+
Contract None => NilClass
|
26
|
+
# Writes the 'elm-stuff/exact-dependencies.json'
|
64
27
|
#
|
65
|
-
# @return
|
66
|
-
def write_exact_dependencies
|
28
|
+
# @return nil
|
29
|
+
def write_exact_dependencies
|
67
30
|
File.binwrite(
|
68
31
|
File.join('elm-stuff', 'exact-dependencies.json'),
|
69
|
-
JSON.pretty_generate(
|
32
|
+
JSON.pretty_generate(exact_dependencies)
|
70
33
|
)
|
34
|
+
nil
|
71
35
|
end
|
72
36
|
|
73
|
-
|
37
|
+
Contract None => HashOf[String => String]
|
38
|
+
# Returns the contents for 'elm-stuff/exact-dependencies.json'
|
74
39
|
#
|
75
|
-
# @
|
40
|
+
# @return [Hash] The dependencies
|
41
|
+
def exact_dependencies
|
42
|
+
@dependencies.each_with_object({}) do |dependency, memo|
|
43
|
+
memo[dependency.name] = dependency.version.to_simple
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Contract None => NilClass
|
48
|
+
# Copies dependencies to 'elm-stuff/packages/package/version' directory
|
76
49
|
#
|
77
|
-
# @return
|
78
|
-
def
|
79
|
-
|
80
|
-
|
50
|
+
# @return nil
|
51
|
+
def copy_dependencies
|
52
|
+
@dependencies.each do |dependency|
|
53
|
+
path =
|
54
|
+
File.join('elm-stuff', 'packages', dependency.name,
|
55
|
+
dependency.version.to_simple)
|
81
56
|
|
82
|
-
|
57
|
+
log_dependency dependency
|
58
|
+
|
59
|
+
dependency.source.copy_to(dependency.version, Pathname.new(path))
|
83
60
|
end
|
61
|
+
nil
|
84
62
|
end
|
85
63
|
|
86
|
-
|
64
|
+
Contract Dependency => NilClass
|
65
|
+
# Logs the dependency with a dot
|
87
66
|
#
|
88
|
-
# @param
|
67
|
+
# @param dependency [Dependency] The dependency
|
89
68
|
#
|
90
|
-
# @return
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
69
|
+
# @return nil
|
70
|
+
def log_dependency(dependency)
|
71
|
+
log = "#{dependency.name} - "
|
72
|
+
log += dependency.source.to_log.to_s
|
73
|
+
log += " (#{dependency.version.to_simple})"
|
74
|
+
|
75
|
+
Logger.dot log
|
76
|
+
nil
|
98
77
|
end
|
99
78
|
end
|
100
79
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module ElmInstall
|
2
|
+
# Handles git repositories.
|
3
|
+
class Repository < Base
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
# The url of the git repository
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :url
|
9
|
+
|
10
|
+
# The path to the directory where the repository lives
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :path
|
13
|
+
|
14
|
+
def_delegators :repo, :fetch
|
15
|
+
|
16
|
+
Contract String, String => Repository
|
17
|
+
# Initializes a repository.
|
18
|
+
#
|
19
|
+
# @param url [String] The url
|
20
|
+
# @param path [String] The path
|
21
|
+
#
|
22
|
+
# @return [Repository] The repository instance
|
23
|
+
def initialize(url, path)
|
24
|
+
@path = path
|
25
|
+
@url = url
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
Contract String => Dir
|
30
|
+
# Checks out the version and returns it's directory
|
31
|
+
#
|
32
|
+
# @param ref [String] The reference to checkout
|
33
|
+
#
|
34
|
+
# @return [Dir] The directory
|
35
|
+
def checkout(ref)
|
36
|
+
repo.checkout ref
|
37
|
+
directory
|
38
|
+
end
|
39
|
+
|
40
|
+
Contract None => Dir
|
41
|
+
# Returns the directory of the repository
|
42
|
+
#
|
43
|
+
# @return [Dir] The directory
|
44
|
+
def directory
|
45
|
+
# This removes the .git from filename
|
46
|
+
Dir.new(File.dirname(repo.repo.path))
|
47
|
+
end
|
48
|
+
|
49
|
+
Contract None => ArrayOf[Semverse::Version]
|
50
|
+
# Returns the versions of the repository
|
51
|
+
#
|
52
|
+
# @return [Array<Semverse::Version>] The versions
|
53
|
+
def versions
|
54
|
+
repo
|
55
|
+
.tags
|
56
|
+
.map(&:name)
|
57
|
+
.map { |tag| Semverse::Version.try_new tag }
|
58
|
+
.compact
|
59
|
+
end
|
60
|
+
|
61
|
+
Contract None => Git::Base
|
62
|
+
# Returns the existing repository or clones it if it does not exists.
|
63
|
+
#
|
64
|
+
# @return [Git::Base]
|
65
|
+
def repo
|
66
|
+
clone unless Dir.exist?(path)
|
67
|
+
@repo ||= Git.open path
|
68
|
+
@repo.reset_hard
|
69
|
+
@repo
|
70
|
+
end
|
71
|
+
|
72
|
+
Contract None => Git::Base
|
73
|
+
# Clones the repository
|
74
|
+
#
|
75
|
+
# @return [Git::Base]
|
76
|
+
def clone
|
77
|
+
Logger.arrow "Package: #{url.bold} not found in cache, cloning..."
|
78
|
+
FileUtils.mkdir_p path
|
79
|
+
@repo = Git.clone(url, path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/elm_install/resolver.rb
CHANGED
@@ -1,145 +1,75 @@
|
|
1
|
-
require_relative './cache'
|
2
|
-
require_relative './utils'
|
3
|
-
|
4
1
|
module ElmInstall
|
5
|
-
# Resolves
|
6
|
-
class Resolver
|
7
|
-
# @return [Array] The
|
8
|
-
attr_reader :
|
9
|
-
|
10
|
-
# Initializes a resolver with a chace and git resolver.
|
11
|
-
#
|
12
|
-
# @param cache [Cache] The cache
|
13
|
-
# @param git_resolver [GitResolver] The git resolver
|
14
|
-
def initialize(cache, git_resolver)
|
15
|
-
@git_resolver = git_resolver
|
16
|
-
@constraints = []
|
17
|
-
@cache = cache
|
18
|
-
end
|
2
|
+
# Resolves dependencies
|
3
|
+
class Resolver < Base
|
4
|
+
# @return [Array<Dependency>] The dependencies
|
5
|
+
attr_reader :dependencies
|
19
6
|
|
20
|
-
|
7
|
+
Contract Identifier => Resolver
|
8
|
+
# Initializes a resolver
|
21
9
|
#
|
22
|
-
# @param
|
10
|
+
# @param identifier [Identifier] The identifier
|
23
11
|
#
|
24
|
-
# @return [
|
25
|
-
def
|
26
|
-
@
|
27
|
-
|
28
|
-
|
12
|
+
# @return [Resolver]
|
13
|
+
def initialize(identifier)
|
14
|
+
@graph = Solve::Graph.new
|
15
|
+
@identifier = identifier
|
16
|
+
@dependencies = {}
|
17
|
+
self
|
29
18
|
end
|
30
19
|
|
31
|
-
|
32
|
-
#
|
33
|
-
# :reek:NestedIterators { max_allowed_nesting: 2 }
|
20
|
+
Contract None => Solve::Graph
|
21
|
+
# Resolves the constraints for a version
|
34
22
|
#
|
35
|
-
# @
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def add_dependencies(dependencies)
|
40
|
-
dependencies.flat_map do |package, constraint|
|
41
|
-
add_package(package)
|
42
|
-
|
43
|
-
constraints = Utils.transform_constraint(constraint)
|
44
|
-
next add_ref_dependency(package, constraint) if constraints.empty?
|
45
|
-
|
46
|
-
constraints.map do |dependency|
|
47
|
-
yield package, dependency
|
48
|
-
end
|
23
|
+
# @return [Solve::Graph] Returns the graph
|
24
|
+
def resolve
|
25
|
+
@identifier.initial_dependencies.each do |dependency|
|
26
|
+
resolve_dependency dependency
|
49
27
|
end
|
50
|
-
end
|
51
28
|
|
52
|
-
|
53
|
-
#
|
54
|
-
# @param package [String] The package
|
55
|
-
# @param ref [String] The reference
|
56
|
-
#
|
57
|
-
# @return [void]
|
58
|
-
def add_ref_dependency(package, ref)
|
59
|
-
@git_resolver.repository(package).checkout(ref)
|
60
|
-
pkg_version = elm_package(package)['version']
|
61
|
-
version = "#{pkg_version}+#{ref}"
|
62
|
-
@cache.ensure_version(package, version)
|
63
|
-
add_package_dependencies(package, version)
|
64
|
-
[[package, "= #{version}"]]
|
29
|
+
@graph
|
65
30
|
end
|
66
31
|
|
67
|
-
|
68
|
-
#
|
69
|
-
# * Getting all the tags and adding the valid ones to the cache
|
70
|
-
# * Checking out and getting the `elm-package.json` for each version
|
71
|
-
# and adding them recursivly
|
32
|
+
Contract Dependency => NilClass
|
33
|
+
# Resolves the dependencies of a dependency
|
72
34
|
#
|
73
|
-
# @param
|
35
|
+
# @param dependency [Dependency] The dependency
|
74
36
|
#
|
75
|
-
# @return
|
76
|
-
def
|
77
|
-
return if @
|
37
|
+
# @return nil
|
38
|
+
def resolve_dependency(dependency)
|
39
|
+
return if @dependencies[dependency.name]
|
40
|
+
|
41
|
+
@dependencies[dependency.name] ||= dependency
|
78
42
|
|
79
|
-
|
80
|
-
.
|
81
|
-
.
|
82
|
-
.map(&:name)
|
43
|
+
dependency
|
44
|
+
.source
|
45
|
+
.versions(dependency.constraints)
|
83
46
|
.each do |version|
|
84
|
-
|
85
|
-
add_version(package, version)
|
47
|
+
resolve_dependencies(dependency, version)
|
86
48
|
end
|
87
|
-
end
|
88
49
|
|
89
|
-
|
90
|
-
#
|
91
|
-
# @param package [String] The package
|
92
|
-
# @param version [String] The version
|
93
|
-
#
|
94
|
-
# @return [void]
|
95
|
-
def add_package_dependencies(package, version)
|
96
|
-
add_dependencies(elm_dependencies(package)) do |dep_package, constraint|
|
97
|
-
add_package(dep_package)
|
98
|
-
@cache.dependency(package, version, [dep_package, constraint])
|
99
|
-
end
|
50
|
+
nil
|
100
51
|
end
|
101
52
|
|
102
|
-
|
53
|
+
Contract Dependency, Semverse::Version => NilClass
|
54
|
+
# Resolves the dependencies of a dependency and version
|
103
55
|
#
|
104
|
-
# @param
|
105
|
-
# @param version [
|
56
|
+
# @param main [Dependency] The dependency
|
57
|
+
# @param version [Semverse::Version] The version
|
106
58
|
#
|
107
|
-
# @return
|
108
|
-
def
|
109
|
-
@
|
110
|
-
|
111
|
-
.checkout(version)
|
112
|
-
|
113
|
-
add_package_dependencies(package, version)
|
114
|
-
end
|
59
|
+
# @return nil
|
60
|
+
def resolve_dependencies(main, version)
|
61
|
+
dependencies = @identifier.identify(main.source.fetch(version))
|
62
|
+
artifact = @graph.artifact main.name, version
|
115
63
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
# @return [Hash] The dependencies
|
121
|
-
def elm_dependencies(package)
|
122
|
-
ElmPackage.dependencies elm_package_path(package)
|
123
|
-
rescue
|
124
|
-
{}
|
125
|
-
end
|
64
|
+
dependencies.each do |dependency|
|
65
|
+
dependency.constraints.each do |constraint|
|
66
|
+
artifact.depends dependency.name, constraint
|
67
|
+
end
|
126
68
|
|
127
|
-
|
128
|
-
|
129
|
-
# @param package [String] The package
|
130
|
-
#
|
131
|
-
# @return [Hash] The contents
|
132
|
-
def elm_package(package)
|
133
|
-
ElmPackage.read elm_package_path(package)
|
134
|
-
end
|
69
|
+
resolve_dependency dependency
|
70
|
+
end
|
135
71
|
|
136
|
-
|
137
|
-
#
|
138
|
-
# @param package [String] The package
|
139
|
-
#
|
140
|
-
# @return [String] The path
|
141
|
-
def elm_package_path(package)
|
142
|
-
File.join(@git_resolver.repository_path(package), 'elm-package.json')
|
72
|
+
nil
|
143
73
|
end
|
144
74
|
end
|
145
75
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ElmInstall
|
2
|
+
# Abstract class for a source
|
3
|
+
class Source < Base
|
4
|
+
# @overload identifier
|
5
|
+
# @return [Identifier] The identifier
|
6
|
+
# @overload identifier=(value)
|
7
|
+
# Sets the identifier
|
8
|
+
# @param [Identifier] The identifier
|
9
|
+
attr_accessor :identifier
|
10
|
+
|
11
|
+
# @overload options
|
12
|
+
# @return [Hash] The options
|
13
|
+
# @overload options=(value)
|
14
|
+
# Sets the options
|
15
|
+
# @param [Hash] The options
|
16
|
+
attr_accessor :options
|
17
|
+
end
|
18
|
+
end
|