elm_install 0.1.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 +7 -0
- data/.gitignore +5 -0
- data/.rubocop.yml +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +115 -0
- data/Rakefile +8 -0
- data/Readme.md +74 -0
- data/bin/elm-install +17 -0
- data/elm_install.gemspec +30 -0
- data/lib/elm_install.rb +19 -0
- data/lib/elm_install/cache.rb +87 -0
- data/lib/elm_install/graph_builder.rb +62 -0
- data/lib/elm_install/installer.rb +107 -0
- data/lib/elm_install/resolver.rb +93 -0
- data/lib/elm_install/utils.rb +38 -0
- data/lib/elm_install/version.rb +3 -0
- metadata +137 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1f5a56400929b580f8e2aef6cfddae1d98c7fe43
|
|
4
|
+
data.tar.gz: 6cb79fca1fe9aa577a7f02495a27b2d15e896eb1
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 20a1ee8f69fc2da9b1d94bd3bdbadb1e1b07e5ef2a879465d71a6c76260d29b688003a0098177565495506886de7faf2405809d2c0ab3cb3dd74cab0b0224ebc
|
|
7
|
+
data.tar.gz: 5a476a8769744e1dd5b86fa7c7cf66f8636bdda9fdac0bde39d92060bd4ddbac47cfc3a062cbfb26c5cf61cabd033957a9aca38547cd732ecae2ab22c70127c7
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
elm-install
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.3.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
elm_install (0.1.0)
|
|
5
|
+
colorize (~> 0.8.1)
|
|
6
|
+
commander (~> 4.4, >= 4.4.2)
|
|
7
|
+
git (~> 1.3)
|
|
8
|
+
git_clone_url (~> 2.0)
|
|
9
|
+
solve (~> 3.1)
|
|
10
|
+
|
|
11
|
+
GEM
|
|
12
|
+
remote: https://rubygems.org/
|
|
13
|
+
specs:
|
|
14
|
+
addressable (2.5.0)
|
|
15
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
|
16
|
+
ast (2.3.0)
|
|
17
|
+
axiom-types (0.1.1)
|
|
18
|
+
descendants_tracker (~> 0.0.4)
|
|
19
|
+
ice_nine (~> 0.11.0)
|
|
20
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
21
|
+
codeclimate-engine-rb (0.4.0)
|
|
22
|
+
virtus (~> 1.0)
|
|
23
|
+
coercible (1.0.0)
|
|
24
|
+
descendants_tracker (~> 0.0.1)
|
|
25
|
+
colorize (0.8.1)
|
|
26
|
+
commander (4.4.2)
|
|
27
|
+
highline (~> 1.7.2)
|
|
28
|
+
descendants_tracker (0.0.4)
|
|
29
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
30
|
+
diff-lcs (1.2.5)
|
|
31
|
+
equalizer (0.0.11)
|
|
32
|
+
erubis (2.7.0)
|
|
33
|
+
flay (2.8.1)
|
|
34
|
+
erubis (~> 2.7.0)
|
|
35
|
+
path_expander (~> 1.0)
|
|
36
|
+
ruby_parser (~> 3.0)
|
|
37
|
+
sexp_processor (~> 4.0)
|
|
38
|
+
flog (4.4.0)
|
|
39
|
+
path_expander (~> 1.0)
|
|
40
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
|
41
|
+
sexp_processor (~> 4.4)
|
|
42
|
+
git (1.3.0)
|
|
43
|
+
git_clone_url (2.0.0)
|
|
44
|
+
uri-ssh_git (>= 2.0)
|
|
45
|
+
highline (1.7.8)
|
|
46
|
+
ice_nine (0.11.2)
|
|
47
|
+
launchy (2.4.3)
|
|
48
|
+
addressable (~> 2.3)
|
|
49
|
+
molinillo (0.5.4)
|
|
50
|
+
parser (2.3.3.1)
|
|
51
|
+
ast (~> 2.2)
|
|
52
|
+
path_expander (1.0.1)
|
|
53
|
+
powerpack (0.1.1)
|
|
54
|
+
public_suffix (2.0.4)
|
|
55
|
+
rainbow (2.1.0)
|
|
56
|
+
reek (4.5.3)
|
|
57
|
+
codeclimate-engine-rb (~> 0.4.0)
|
|
58
|
+
parser (~> 2.3.1, >= 2.3.1.2)
|
|
59
|
+
rainbow (~> 2.0)
|
|
60
|
+
rspec (3.5.0)
|
|
61
|
+
rspec-core (~> 3.5.0)
|
|
62
|
+
rspec-expectations (~> 3.5.0)
|
|
63
|
+
rspec-mocks (~> 3.5.0)
|
|
64
|
+
rspec-core (3.5.4)
|
|
65
|
+
rspec-support (~> 3.5.0)
|
|
66
|
+
rspec-expectations (3.5.0)
|
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
|
+
rspec-support (~> 3.5.0)
|
|
69
|
+
rspec-mocks (3.5.0)
|
|
70
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
71
|
+
rspec-support (~> 3.5.0)
|
|
72
|
+
rspec-support (3.5.0)
|
|
73
|
+
rubocop (0.46.0)
|
|
74
|
+
parser (>= 2.3.1.1, < 3.0)
|
|
75
|
+
powerpack (~> 0.1)
|
|
76
|
+
rainbow (>= 1.99.1, < 3.0)
|
|
77
|
+
ruby-progressbar (~> 1.7)
|
|
78
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
79
|
+
ruby-progressbar (1.8.1)
|
|
80
|
+
ruby_parser (3.8.3)
|
|
81
|
+
sexp_processor (~> 4.1)
|
|
82
|
+
rubycritic (3.1.3)
|
|
83
|
+
flay (~> 2.8)
|
|
84
|
+
flog (~> 4.4)
|
|
85
|
+
launchy (= 2.4.3)
|
|
86
|
+
parser (= 2.3.3.1)
|
|
87
|
+
rainbow (~> 2.1)
|
|
88
|
+
reek (~> 4.4)
|
|
89
|
+
ruby_parser (~> 3.8)
|
|
90
|
+
virtus (~> 1.0)
|
|
91
|
+
semverse (2.0.0)
|
|
92
|
+
sexp_processor (4.7.0)
|
|
93
|
+
solve (3.1.0)
|
|
94
|
+
molinillo (>= 0.5)
|
|
95
|
+
semverse (>= 1.1, < 3.0)
|
|
96
|
+
thread_safe (0.3.5)
|
|
97
|
+
unicode-display_width (1.1.2)
|
|
98
|
+
uri-ssh_git (2.0.0)
|
|
99
|
+
virtus (1.0.5)
|
|
100
|
+
axiom-types (~> 0.1)
|
|
101
|
+
coercible (~> 1.0)
|
|
102
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
103
|
+
equalizer (~> 0.0, >= 0.0.9)
|
|
104
|
+
|
|
105
|
+
PLATFORMS
|
|
106
|
+
ruby
|
|
107
|
+
|
|
108
|
+
DEPENDENCIES
|
|
109
|
+
elm_install!
|
|
110
|
+
rspec (~> 3.5)
|
|
111
|
+
rubocop (~> 0.46.0)
|
|
112
|
+
rubycritic (~> 3.1, >= 3.1.3)
|
|
113
|
+
|
|
114
|
+
BUNDLED WITH
|
|
115
|
+
1.13.6
|
data/Rakefile
ADDED
data/Readme.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# elm-github-install
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/elm-github-install)
|
|
4
|
+
|
|
5
|
+
This node script and package that allows you to install Elm packages **directly
|
|
6
|
+
from Github**, bypassing the package repository (package.elm-lang.org) while also
|
|
7
|
+
enabling restricted (effect manager and native) packages to be installed.
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
There are some things that made this possible:
|
|
12
|
+
* The basic design of Elm packages: using github, semantic versioning and tags
|
|
13
|
+
* [Semver package](https://www.npmjs.com/package/semver) to validate versions
|
|
14
|
+
* [SemverResolver package](https://github.com/pghalliday/semver-resolver) that
|
|
15
|
+
does the actual resolving
|
|
16
|
+
|
|
17
|
+
These are the steps the installer takes:
|
|
18
|
+
* Reads the dependencies from `elm-package.json`
|
|
19
|
+
* Transforms them to semver dependencies - **4.0.4 <= v < 5.0.0** becomes
|
|
20
|
+
**>= 4.0.4 < 5.0.0**
|
|
21
|
+
* Loads the dependencies of the packages form Github and transforms them also
|
|
22
|
+
* Resolve the dependencies
|
|
23
|
+
* Install resolved dependencies into `elm-stuff/packages`
|
|
24
|
+
* Writes `elm-stuff/exact-dependencies.json` with the resolved dependencies
|
|
25
|
+
|
|
26
|
+
## Warnings
|
|
27
|
+
|
|
28
|
+
There are some caveats though:
|
|
29
|
+
* [TODO] This installer doesn't check the installed elm-version
|
|
30
|
+
* [DEPENDENCY] Git tags (semver) are needed other references cannot be installed
|
|
31
|
+
(branch-name, commit-hash)
|
|
32
|
+
* [DEPENDENCY] Git is needed
|
|
33
|
+
* [DEPENDENCY] Node is needed
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
Install it:
|
|
38
|
+
```
|
|
39
|
+
npm install -g elm-github-install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Elm packages are name after their github repositories, so you can simply declare the
|
|
43
|
+
github package you want the way you would declare any other package.
|
|
44
|
+
For example, if you want to install [NoRedInk's Elm css](https://github.com/NoRedInk/nri-elm-css)
|
|
45
|
+
at version 1.3.0, you would do the following:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
# elm-package.json
|
|
49
|
+
{
|
|
50
|
+
...
|
|
51
|
+
"dependencies": {
|
|
52
|
+
...
|
|
53
|
+
"githubUser/repoName": "desiredVersion <= v < someLargerNumber",
|
|
54
|
+
"NoRedInk/nri-elm-css": "1.3.0 <= 1.3.0 < 2.0.0",
|
|
55
|
+
...
|
|
56
|
+
}
|
|
57
|
+
...
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
You can find the current version of the package in the repository's `elm-package.json`.
|
|
62
|
+
|
|
63
|
+
Use the command:
|
|
64
|
+
```
|
|
65
|
+
elm-github-install
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Demonstration
|
|
69
|
+
The following repositories have their packages successfully installed and
|
|
70
|
+
the main file successfully compiled (2016-06-12):
|
|
71
|
+
* [STANDARD] https://github.com/debois/elm-mdl/tree/v7/demo - Demo.elm
|
|
72
|
+
* [STANDARD] https://github.com/evancz/elm-sortable-table/tree/master/examples -
|
|
73
|
+
1-presidents.elm
|
|
74
|
+
* [HAVE GITHUB DEPS] https://github.com/gdotdesign/elm-ui-website - source/Main.elm
|
data/bin/elm-install
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'commander/import'
|
|
5
|
+
require 'elm_install'
|
|
6
|
+
|
|
7
|
+
program :name, 'elm-install'
|
|
8
|
+
program :version, ElmInstall::VERSION
|
|
9
|
+
program :description, 'Install Elm packages from Git repositories.'
|
|
10
|
+
|
|
11
|
+
command :install do |c|
|
|
12
|
+
c.syntax = 'elm-install install'
|
|
13
|
+
c.summary = 'Install Elm packages from the elm-package.json file.'
|
|
14
|
+
c.action do
|
|
15
|
+
ElmInstall.install
|
|
16
|
+
end
|
|
17
|
+
end
|
data/elm_install.gemspec
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require File.expand_path('../lib/elm_install/version', __FILE__)
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = 'elm_install'
|
|
5
|
+
s.version = ElmInstall::VERSION
|
|
6
|
+
s.authors = ['Gusztáv Szikszai']
|
|
7
|
+
s.email = 'gusztav.szikszai@digitalnatives.hu'
|
|
8
|
+
s.homepage = 'https://github.com/gdotdesign/elm-github-install'
|
|
9
|
+
s.summary = 'Install Elm packages from git repositories.'
|
|
10
|
+
s.require_paths = ['lib']
|
|
11
|
+
|
|
12
|
+
s.files =
|
|
13
|
+
`git ls-files`.split("\n")
|
|
14
|
+
|
|
15
|
+
s.test_files =
|
|
16
|
+
`git ls-files -- {test,spec,features}/*`.split("\n")
|
|
17
|
+
|
|
18
|
+
puts `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
19
|
+
|
|
20
|
+
s.executables =
|
|
21
|
+
`git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
22
|
+
|
|
23
|
+
s.add_dependency 'git', '~> 1.3'
|
|
24
|
+
s.add_dependency 'git_clone_url', '~> 2.0'
|
|
25
|
+
s.add_dependency 'solve', '~> 3.1'
|
|
26
|
+
s.add_dependency 'commander', '~> 4.4', '>= 4.4.2'
|
|
27
|
+
s.add_dependency 'colorize', '~> 0.8.1'
|
|
28
|
+
|
|
29
|
+
s.extra_rdoc_files = ['Readme.md']
|
|
30
|
+
end
|
data/lib/elm_install.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'git_clone_url'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'colorize'
|
|
5
|
+
require 'solve'
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'git'
|
|
8
|
+
|
|
9
|
+
require_relative './elm_install/version'
|
|
10
|
+
require_relative './elm_install/installer'
|
|
11
|
+
|
|
12
|
+
# The main module for the gem.
|
|
13
|
+
module ElmInstall
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def install(options = { verbose: false })
|
|
17
|
+
Installer.new(options).install
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require_relative './graph_builder'
|
|
2
|
+
|
|
3
|
+
module ElmInstall
|
|
4
|
+
# This class is responsible for maintaining a cache
|
|
5
|
+
# of all the repositories their versions and their dependencies.
|
|
6
|
+
#
|
|
7
|
+
# By default the clones of the repositories live in the users
|
|
8
|
+
# home directory (~/.elm-install), this can be changed with
|
|
9
|
+
# the `directory` option.
|
|
10
|
+
class Cache
|
|
11
|
+
extend Forwardable
|
|
12
|
+
|
|
13
|
+
def_delegators :@cache, :each
|
|
14
|
+
|
|
15
|
+
# Initializes a new cache with the given options.
|
|
16
|
+
def initialize(options = {})
|
|
17
|
+
@options = options
|
|
18
|
+
@cache = {}
|
|
19
|
+
load
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Saves the cache into the json file.
|
|
23
|
+
def save
|
|
24
|
+
File.binwrite(file, JSON.pretty_generate(@cache))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Loads a cache from the json file.
|
|
28
|
+
def load
|
|
29
|
+
@cache = JSON.parse(File.read(file))
|
|
30
|
+
rescue
|
|
31
|
+
@cache = {}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns the directory where the cache is stored.
|
|
35
|
+
def directory
|
|
36
|
+
@options[:directory] || File.join(Dir.home, '.elm-install')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns if there is a package in the cache (with at least one version).
|
|
40
|
+
def package?(package)
|
|
41
|
+
@cache.key?(package)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Adds a new dependency to the cache for a given package & version
|
|
45
|
+
# combination.
|
|
46
|
+
def dependency(package, version, constraint)
|
|
47
|
+
ensure_package version
|
|
48
|
+
@cache[package][version] << constraint
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Ensures that a package & version combination exists in the cache.
|
|
52
|
+
def ensure_version(package, version)
|
|
53
|
+
ensure_package package
|
|
54
|
+
@cache[package][version] ||= []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Ensures that a package exists in the cache.
|
|
58
|
+
def ensure_package(package)
|
|
59
|
+
@cache[package] ||= {}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns the path to the repository of the given package.
|
|
63
|
+
def repository_path(package)
|
|
64
|
+
File.join(directory, package)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Returns the Git repository of the given package in a ready to use state.
|
|
68
|
+
def repository(path)
|
|
69
|
+
repo_path = repository_path(path)
|
|
70
|
+
|
|
71
|
+
if Dir.exist?(repo_path)
|
|
72
|
+
repo = Git.open(repo_path)
|
|
73
|
+
repo.reset_hard
|
|
74
|
+
repo
|
|
75
|
+
else
|
|
76
|
+
Git.clone(path, repo_path)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Returns the path to the json file.
|
|
83
|
+
def file
|
|
84
|
+
File.join(directory, 'cache.json')
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module ElmInstall
|
|
2
|
+
# This class is for building dependency graphs from a cache.
|
|
3
|
+
class GraphBuilder
|
|
4
|
+
attr_reader :graph
|
|
5
|
+
|
|
6
|
+
# Returns a graph from a cache.
|
|
7
|
+
def self.graph_from_cache(cache, options = { verbose: false })
|
|
8
|
+
graph = new cache, options
|
|
9
|
+
graph.build
|
|
10
|
+
graph.graph
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Initialies a graph build with a cache
|
|
14
|
+
def initialize(cache, options = { verbose: false })
|
|
15
|
+
@graph = Solve::Graph.new
|
|
16
|
+
@options = options
|
|
17
|
+
@cache = cache
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Builds the graph.
|
|
21
|
+
def build
|
|
22
|
+
@cache.each do |package, versions|
|
|
23
|
+
add_versions package, versions
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
# Adds the given package & version combinations to the graph.
|
|
30
|
+
def add_versions(package, versions)
|
|
31
|
+
versions.each do |version, dependencies|
|
|
32
|
+
add_version package, version, dependencies
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Adds the given package, version and dependency
|
|
37
|
+
# combinations to the graph.
|
|
38
|
+
def add_version(package, version, dependencies)
|
|
39
|
+
artifact = @graph.artifact(package, version)
|
|
40
|
+
|
|
41
|
+
dependencies.each do |dependency|
|
|
42
|
+
add_dependency artifact, *dependency
|
|
43
|
+
end
|
|
44
|
+
rescue
|
|
45
|
+
if @options[:verbose]
|
|
46
|
+
puts "WARNING: Could not add version #{version} to #{package}."
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Adds the given package version and single dependency to the
|
|
51
|
+
# graph.
|
|
52
|
+
def add_dependency(artifact, package, version)
|
|
53
|
+
artifact.depends package, version
|
|
54
|
+
rescue
|
|
55
|
+
if @options[:verbose]
|
|
56
|
+
puts "
|
|
57
|
+
WARNING: Could not add dependency #{package}-#{version} to #{artifact}
|
|
58
|
+
".strip
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require_relative './resolver'
|
|
2
|
+
|
|
3
|
+
module ElmInstall
|
|
4
|
+
# This class is responsible getting a solution for the `elm-package.json`
|
|
5
|
+
# file and populating the `elm-stuff` directory with the packages and
|
|
6
|
+
# writing the `elm-stuff/exact-dependencies.json`.
|
|
7
|
+
class Installer
|
|
8
|
+
extend Forwardable
|
|
9
|
+
|
|
10
|
+
# Initializes a new installer with the given options.
|
|
11
|
+
def initialize(options = { verbose: false })
|
|
12
|
+
@options = options
|
|
13
|
+
@cache = Cache.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Executes the installation
|
|
17
|
+
#
|
|
18
|
+
# :reek:TooManyStatements { max_statements: 7 }
|
|
19
|
+
def install
|
|
20
|
+
puts 'Resolving packages...'
|
|
21
|
+
resolver.add_constraints dependencies
|
|
22
|
+
|
|
23
|
+
puts 'Saving index cache...'
|
|
24
|
+
@cache.save
|
|
25
|
+
|
|
26
|
+
puts 'Solving dependencies...'
|
|
27
|
+
populate_elm_stuff
|
|
28
|
+
|
|
29
|
+
puts 'Packages configured successfully!'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Populates the `elm-stuff` directory with the packages from
|
|
35
|
+
# the solution.
|
|
36
|
+
def populate_elm_stuff
|
|
37
|
+
solution.each do |package, version|
|
|
38
|
+
resolve_package package, version
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
write_exact_dependencies
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Resolves and copies a package and it's version to `elm-stuff/packages`
|
|
45
|
+
# directory.
|
|
46
|
+
#
|
|
47
|
+
# :reek:TooManyStatements { max_statements: 9 }
|
|
48
|
+
def resolve_package(package, version)
|
|
49
|
+
package_name, package_path = Utils.package_version_path package, version
|
|
50
|
+
|
|
51
|
+
matches = dependencies[package_name].to_s.match(/^(ref|branch):(.*)/)
|
|
52
|
+
|
|
53
|
+
ref = (matches && matches[2]) || version
|
|
54
|
+
@cache.repository(package).checkout(ref)
|
|
55
|
+
|
|
56
|
+
version_str = ref == version ? ref : "#{ref}(#{version})"
|
|
57
|
+
Utils.log_with_dot "#{package_name} - #{version_str}"
|
|
58
|
+
|
|
59
|
+
return if Dir.exist?(package_path)
|
|
60
|
+
|
|
61
|
+
copy_package package, package_path
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Copies the given package from it's repository to the given path.
|
|
65
|
+
def copy_package(package, package_path)
|
|
66
|
+
FileUtils.mkdir_p(package_path)
|
|
67
|
+
FileUtils.cp_r(
|
|
68
|
+
File.join(@cache.repository_path(package), '.'), package_path
|
|
69
|
+
)
|
|
70
|
+
FileUtils.rm_rf(File.join(package_path, '.git'))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Writes the `elm-stuff/exact-dependencies.json` file.
|
|
74
|
+
def write_exact_dependencies
|
|
75
|
+
path = File.join('elm-stuff', 'exact-dependencies.json')
|
|
76
|
+
File.binwrite(path, JSON.pretty_generate(exact_dependencies))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns the exact dependencies from the solution.
|
|
80
|
+
def exact_dependencies
|
|
81
|
+
@exact_dependencies ||=
|
|
82
|
+
solution.each_with_object({}) do |(key, value), memo|
|
|
83
|
+
memo[GitCloneUrl.parse(key).path] = value
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Returns the resolver to calculate the solution.
|
|
88
|
+
def resolver
|
|
89
|
+
@resolver ||= Resolver.new @cache
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Returns the solution for the given `elm-package.json` file.
|
|
93
|
+
def solution
|
|
94
|
+
@solution ||=
|
|
95
|
+
Solve.it!(
|
|
96
|
+
GraphBuilder.graph_from_cache(@cache, @options),
|
|
97
|
+
resolver.constraints
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Returns the dependencies from the `elm-package.json` file.
|
|
102
|
+
def dependencies
|
|
103
|
+
@dependencies ||=
|
|
104
|
+
JSON.parse(File.read('elm-package.json'))['dependencies']
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require_relative './cache'
|
|
2
|
+
require_relative './utils'
|
|
3
|
+
|
|
4
|
+
module ElmInstall
|
|
5
|
+
# Resolves git dependencies into the cache.
|
|
6
|
+
class Resolver
|
|
7
|
+
attr_reader :constraints
|
|
8
|
+
|
|
9
|
+
# Initializes a resolver for a chace.
|
|
10
|
+
def initialize(cache)
|
|
11
|
+
@constraints = []
|
|
12
|
+
@cache = cache
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Add constrains, usually from the `elm-package.json`.
|
|
16
|
+
def add_constraints(constraints)
|
|
17
|
+
@constraints = add_dependencies(constraints) do |package, constraint|
|
|
18
|
+
[package, constraint]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Adds dependencies, usually from any `elm-package.json` file.
|
|
23
|
+
#
|
|
24
|
+
# :reek:NestedIterators { max_allowed_nesting: 2 }
|
|
25
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
|
26
|
+
def add_dependencies(dependencies)
|
|
27
|
+
dependencies.flat_map do |package_slug, constraint|
|
|
28
|
+
package = Utils.transform_package(package_slug)
|
|
29
|
+
|
|
30
|
+
add_package(package)
|
|
31
|
+
|
|
32
|
+
if constraint =~ /^(ref|branch):(.*)/
|
|
33
|
+
next add_ref_dependency(package, constraint)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Utils.transform_constraint(constraint).map do |dependency|
|
|
37
|
+
yield package, dependency
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Adds a dependency by git reference.
|
|
43
|
+
def add_ref_dependency(package, constraint)
|
|
44
|
+
ref = constraint.match(/^(ref|branch):(.*)/)[2]
|
|
45
|
+
@cache.repository(package).checkout(ref)
|
|
46
|
+
[[package, "= #{elm_package(package)['version']}"]]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Adds a package to the cache, the following things happens:
|
|
50
|
+
# * If there is no local repository it will be cloned
|
|
51
|
+
# * Getting all the tags and adding the valid ones to the cache
|
|
52
|
+
# * Checking out and getting the `elm-package.json` for each version
|
|
53
|
+
# and adding them recursivly
|
|
54
|
+
def add_package(package)
|
|
55
|
+
return if @cache.package?(package)
|
|
56
|
+
|
|
57
|
+
Utils.log_with_dot "Package: #{package} not found in cache, cloning..."
|
|
58
|
+
|
|
59
|
+
@cache
|
|
60
|
+
.repository(package)
|
|
61
|
+
.tags
|
|
62
|
+
.map(&:name)
|
|
63
|
+
.each do |version|
|
|
64
|
+
@cache.ensure_version(package, version)
|
|
65
|
+
add_version(package, version)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Adds a version and it's dependencies to the cache.
|
|
70
|
+
def add_version(package, version)
|
|
71
|
+
@cache
|
|
72
|
+
.repository(package)
|
|
73
|
+
.checkout(version)
|
|
74
|
+
|
|
75
|
+
add_dependencies(elm_dependencies(package)) do |dep_package, constraint|
|
|
76
|
+
add_package(dep_package)
|
|
77
|
+
@cache.dependency(package, version, [dep_package, constraint])
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Gets the `elm-package.json` for a package.
|
|
82
|
+
def elm_dependencies(package)
|
|
83
|
+
elm_package(package)['dependencies']
|
|
84
|
+
rescue
|
|
85
|
+
[]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def elm_package(package)
|
|
89
|
+
path = File.join(@cache.repository_path(package), 'elm-package.json')
|
|
90
|
+
JSON.parse(File.read(path))
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ElmInstall
|
|
2
|
+
# This module contains utility functions.
|
|
3
|
+
module Utils
|
|
4
|
+
module_function
|
|
5
|
+
|
|
6
|
+
CONVERTERS = {
|
|
7
|
+
/v<(?!=)(.*)/ => '<',
|
|
8
|
+
/(.*)<=v/ => '>=',
|
|
9
|
+
/v<=(.*)/ => '<=',
|
|
10
|
+
/(.*)<v/ => '>'
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
def transform_constraint(constraint)
|
|
14
|
+
constraint.gsub!(/\s/, '')
|
|
15
|
+
|
|
16
|
+
CONVERTERS.map do |regexp, prefix|
|
|
17
|
+
match = constraint.match(regexp)
|
|
18
|
+
"#{prefix} #{match[1]}" if match
|
|
19
|
+
end.compact
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def log_with_dot(message)
|
|
23
|
+
puts ' ● '.green + message
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def package_version_path(package, version)
|
|
27
|
+
package_name = GitCloneUrl.parse(package).path
|
|
28
|
+
[package_name, File.join('elm-stuff', 'packages', package_name, version)]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def transform_package(key)
|
|
32
|
+
GitCloneUrl.parse(key)
|
|
33
|
+
key
|
|
34
|
+
rescue
|
|
35
|
+
"git@github.com:#{key}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: elm_install
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Gusztáv Szikszai
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-12-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: git
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.3'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: git_clone_url
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: solve
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.1'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.1'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: commander
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '4.4'
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: 4.4.2
|
|
65
|
+
type: :runtime
|
|
66
|
+
prerelease: false
|
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - "~>"
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '4.4'
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 4.4.2
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: colorize
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 0.8.1
|
|
82
|
+
type: :runtime
|
|
83
|
+
prerelease: false
|
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: 0.8.1
|
|
89
|
+
description:
|
|
90
|
+
email: gusztav.szikszai@digitalnatives.hu
|
|
91
|
+
executables:
|
|
92
|
+
- elm-install
|
|
93
|
+
extensions: []
|
|
94
|
+
extra_rdoc_files:
|
|
95
|
+
- Readme.md
|
|
96
|
+
files:
|
|
97
|
+
- ".gitignore"
|
|
98
|
+
- ".rubocop.yml"
|
|
99
|
+
- ".ruby-gemset"
|
|
100
|
+
- ".ruby-version"
|
|
101
|
+
- Gemfile
|
|
102
|
+
- Gemfile.lock
|
|
103
|
+
- Rakefile
|
|
104
|
+
- Readme.md
|
|
105
|
+
- bin/elm-install
|
|
106
|
+
- elm_install.gemspec
|
|
107
|
+
- lib/elm_install.rb
|
|
108
|
+
- lib/elm_install/cache.rb
|
|
109
|
+
- lib/elm_install/graph_builder.rb
|
|
110
|
+
- lib/elm_install/installer.rb
|
|
111
|
+
- lib/elm_install/resolver.rb
|
|
112
|
+
- lib/elm_install/utils.rb
|
|
113
|
+
- lib/elm_install/version.rb
|
|
114
|
+
homepage: https://github.com/gdotdesign/elm-github-install
|
|
115
|
+
licenses: []
|
|
116
|
+
metadata: {}
|
|
117
|
+
post_install_message:
|
|
118
|
+
rdoc_options: []
|
|
119
|
+
require_paths:
|
|
120
|
+
- lib
|
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - ">="
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '0'
|
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
requirements: []
|
|
132
|
+
rubyforge_project:
|
|
133
|
+
rubygems_version: 2.5.2
|
|
134
|
+
signing_key:
|
|
135
|
+
specification_version: 4
|
|
136
|
+
summary: Install Elm packages from git repositories.
|
|
137
|
+
test_files: []
|