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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.reek +4 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +4 -0
  5. data/Gemfile.lock +30 -25
  6. data/Rakefile +2 -2
  7. data/Readme.md +85 -23
  8. data/bin/elm-install +5 -2
  9. data/elm_install.gemspec +2 -0
  10. data/lib/elm_install.rb +18 -1
  11. data/lib/elm_install/base.rb +3 -46
  12. data/lib/elm_install/dependency.rb +37 -0
  13. data/lib/elm_install/directory_source.rb +66 -0
  14. data/lib/elm_install/ext.rb +23 -0
  15. data/lib/elm_install/git_source.rb +173 -0
  16. data/lib/elm_install/identifier.rb +133 -0
  17. data/lib/elm_install/installer.rb +38 -96
  18. data/lib/elm_install/populator.rb +54 -75
  19. data/lib/elm_install/repository.rb +82 -0
  20. data/lib/elm_install/resolver.rb +48 -118
  21. data/lib/elm_install/source.rb +18 -0
  22. data/lib/elm_install/types.rb +43 -0
  23. data/lib/elm_install/utils.rb +14 -20
  24. data/lib/elm_install/version.rb +1 -1
  25. data/package.json +1 -1
  26. data/packaging/Gemfile +1 -1
  27. data/packaging/Gemfile.lock +8 -4
  28. data/scripts/install.js +4 -4
  29. data/scripts/run.js +4 -4
  30. data/spec/directory_source_spec.rb +37 -0
  31. data/spec/{eml_install_spec.rb → elm_install_spec.rb} +6 -3
  32. data/spec/git_source_spec.rb +115 -0
  33. data/spec/identifer_spec.rb +53 -0
  34. data/spec/installer_spec.rb +57 -26
  35. data/spec/repository_spec.rb +44 -0
  36. data/spec/resolver_spec.rb +0 -73
  37. data/spec/spec_helper.rb +3 -1
  38. data/spec/utils_spec.rb +10 -15
  39. metadata +43 -17
  40. data/docs/How it works.md +0 -54
  41. data/lib/elm_install/cache.rb +0 -52
  42. data/lib/elm_install/elm_package.rb +0 -119
  43. data/lib/elm_install/git_resolver.rb +0 -129
  44. data/lib/elm_install/graph_builder.rb +0 -73
  45. data/spec/elm_package_spec.rb +0 -73
  46. data/spec/fixtures/cache.json +0 -8
  47. data/spec/fixtures/elm-package.json +0 -12
  48. data/spec/fixtures/invalid-elm-package.json +0 -6
  49. data/spec/fixtures/mismatched-elm-package.json +0 -9
  50. data/spec/fixtures/ref-cache.json +0 -4
  51. data/spec/git_resolver_spec.rb +0 -103
  52. data/spec/graph_builder_spec.rb +0 -36
  53. data/spec/populator_spec.rb +0 -44
@@ -0,0 +1,43 @@
1
+ module ElmInstall
2
+ # Represents a branch
3
+ Branch = ADT do
4
+ Just(ref: String) |
5
+ Nothing()
6
+ end
7
+
8
+ # Represents an uri
9
+ Uri = ADT do
10
+ Ssh(uri: URI::SshGit::Generic) do
11
+ def to_s
12
+ uri.to_s
13
+ end
14
+ end |
15
+
16
+ Http(uri: URI::HTTP) do
17
+ def to_s
18
+ uri.to_s
19
+ end
20
+ end |
21
+
22
+ Github(name: String) do
23
+ def to_s
24
+ "https://github.com/#{name}"
25
+ end
26
+ end
27
+ end
28
+
29
+ # Represents a source type
30
+ Type = ADT do
31
+ Git(uri: Uri, branch: Branch) do
32
+ def source
33
+ @source ||= GitSource.new uri, branch
34
+ end
35
+ end |
36
+
37
+ Directory(path: Pathname) do
38
+ def source
39
+ @source ||= DirectorySource.new path
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,6 +1,9 @@
1
1
  module ElmInstall
2
2
  # This module contains utility functions.
3
3
  module Utils
4
+ include Contracts::Core
5
+ include Contracts::Builtin
6
+
4
7
  module_function
5
8
 
6
9
  # Regexes for converting constraints.
@@ -11,29 +14,20 @@ module ElmInstall
11
14
  /(.*)<v/ => '>'
12
15
  }.freeze
13
16
 
14
- # Transform constraints form Elm's package format to semver's.
17
+ Contract String => [Solve::Constraint]
18
+ # Transform an 'elm' constraint into a proper one.
15
19
  #
16
- # @param constraint [String] The input constraint
20
+ # @param elm_constraint [String] The elm constraint
17
21
  #
18
- # @return [Array] The output constraints
19
- def transform_constraint(constraint)
20
- constraint.gsub!(/\s/, '')
21
-
22
- CONVERTERS.map do |regexp, prefix|
23
- match = constraint.match(regexp)
24
- "#{prefix} #{match[1]}" if match
25
- end.compact
26
- end
22
+ # @return [Array] The transform constraints
23
+ def transform_constraint(elm_constraint)
24
+ elm_constraint.gsub!(/\s/, '')
27
25
 
28
- # Returns the path for a package with the given version.
29
- #
30
- # @param package [String] The package
31
- # @param version [String] The version
32
- #
33
- # @return [Strin] The path
34
- def package_version_path(package, version)
35
- package_name = GitCloneUrl.parse(package).path.sub(%r{^/}, '')
36
- [package_name, File.join('elm-stuff', 'packages', package_name, version)]
26
+ CONVERTERS
27
+ .map { |regexp, prefix| [elm_constraint.match(regexp), prefix] }
28
+ .select { |(match)| match }
29
+ .map { |(match, prefix)| "#{prefix} #{match[1]}" }
30
+ .map { |constraint| Solve::Constraint.new constraint }
37
31
  end
38
32
  end
39
33
  end
@@ -1,4 +1,4 @@
1
1
  module ElmInstall
2
2
  # The version of ElmInstall
3
- VERSION = '0.3.1'.freeze
3
+ VERSION = '1.0.0'.freeze
4
4
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elm-github-install",
3
- "version": "0.3.1",
3
+ "version": "1.0.0",
4
4
  "description": "Install Elm packages directly from Git repositories",
5
5
  "scripts": {
6
6
  "install": "node scripts/install.js",
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  ruby '2.2.2'
4
4
 
5
- gem 'elm_install'
5
+ gem 'elm_install', '1.0.0'
@@ -1,10 +1,14 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
+ adts (0.1.2)
4
5
  commander (4.4.3)
5
6
  highline (~> 1.7.2)
6
- elm_install (0.3.0)
7
+ contracts (0.16.0)
8
+ elm_install (1.0.0.pre.rc)
9
+ adts (~> 0.1.2)
7
10
  commander (~> 4.4, >= 4.4.2)
11
+ contracts (~> 0.16.0)
8
12
  git (~> 1.3)
9
13
  git_clone_url (~> 2.0)
10
14
  hashdiff (~> 0.3.1)
@@ -14,10 +18,10 @@ GEM
14
18
  git (1.3.0)
15
19
  git_clone_url (2.0.0)
16
20
  uri-ssh_git (>= 2.0)
17
- hashdiff (0.3.2)
21
+ hashdiff (0.3.4)
18
22
  highline (1.7.8)
19
23
  indentation (0.1.1)
20
- molinillo (0.5.5)
24
+ molinillo (0.5.7)
21
25
  semverse (2.0.0)
22
26
  smart_colored (1.1.1)
23
27
  solve (3.1.0)
@@ -29,7 +33,7 @@ PLATFORMS
29
33
  ruby
30
34
 
31
35
  DEPENDENCIES
32
- elm_install
36
+ elm_install (= 1.0.0.pre.rc)
33
37
 
34
38
  RUBY VERSION
35
39
  ruby 2.2.2p95
@@ -39,13 +39,13 @@ var download = function(suffix){
39
39
  .pipe(extractor)
40
40
  }
41
41
 
42
- if(platform == 'linux' && arch == 'x64') {
42
+ if(platform === 'linux' && arch === 'x64') {
43
43
  download('linux-x86_64')
44
- } else if (platform == 'linux') {
44
+ } else if (platform === 'linux') {
45
45
  download('linux-x86')
46
- } else if (platform == 'darwin') {
46
+ } else if (platform === 'darwin') {
47
47
  download('osx')
48
- } else if (platform == 'win32') {
48
+ } else if (platform === 'win32') {
49
49
  var tmpFile = tmp.fileSync()
50
50
  var url =
51
51
  [ prefix,
@@ -26,13 +26,13 @@ var executablePath = function(suffix) {
26
26
  )
27
27
  }
28
28
 
29
- if(platform == 'linux' && arch == 'x64') {
29
+ if(platform === 'linux' && arch === 'x64') {
30
30
  execute('linux-x86_64')
31
- } else if (platform == 'linux') {
31
+ } else if (platform === 'linux') {
32
32
  execute('linux-x86')
33
- } else if (platform == 'darwin') {
33
+ } else if (platform === 'darwin') {
34
34
  execute('osx')
35
- } else if (platform == 'win32') {
35
+ } else if (platform === 'win32') {
36
36
  exec(executablePath('win32') + '.bat', [ process.argv.slice(2) ], { stdio: 'inherit' })
37
37
  } else {
38
38
  console.log('Your operating system is not supported.')
@@ -0,0 +1,37 @@
1
+ describe ElmInstall::DirectorySource do
2
+ let(:dir) { Pathname.new('.') }
3
+
4
+ subject { described_class.new dir }
5
+
6
+ describe '#fetch' do
7
+ it 'returns the directory' do
8
+ expect(subject.fetch('').path).to eq dir.expand_path.to_s
9
+ end
10
+ end
11
+
12
+ describe '#copy_to' do
13
+ it 'symlinks the directory' do
14
+ allow(FileUtils).to receive(:rm_rf)
15
+ expect(FileUtils).to receive(:mkdir_p)
16
+ expect(FileUtils).to receive(:ln_s)
17
+ subject.copy_to(Semverse::Version.new('1.0.0'), dir)
18
+ end
19
+ end
20
+
21
+ describe '#versions' do
22
+ let(:identifier) do
23
+ double :identifier, version: Semverse::Version.new('1.0.0')
24
+ end
25
+
26
+ it 'returns version' do
27
+ subject.identifier = identifier
28
+ subject.versions([])
29
+ end
30
+ end
31
+
32
+ describe '#to_log' do
33
+ it 'returns the url' do
34
+ expect(subject.to_log).to eq dir.expand_path.to_s
35
+ end
36
+ end
37
+ end
@@ -1,9 +1,12 @@
1
- require 'spec_helper'
2
-
3
1
  describe ElmInstall do
4
2
  it 'should install packages' do
3
+ expect(ElmInstall::Logger)
4
+ .to receive(:arrow)
5
+ .twice
6
+
5
7
  expect_any_instance_of(ElmInstall::Installer)
6
8
  .to receive(:install)
7
- subject.install
9
+
10
+ subject.install(cache_directory: CACHE_DIRECTORY)
8
11
  end
9
12
  end
@@ -0,0 +1,115 @@
1
+ describe ElmInstall::GitSource do
2
+ subject { described_class.new uri, branch }
3
+
4
+ let(:uri) do
5
+ ElmInstall::Uri::Ssh(GitCloneUrl.parse('git@github.com:test/repo'))
6
+ end
7
+
8
+ let(:branch) do
9
+ ElmInstall::Branch::Nothing()
10
+ end
11
+
12
+ before do
13
+ subject.options = { cache_directory: CACHE_DIRECTORY }
14
+ end
15
+
16
+ let(:repository) do
17
+ double
18
+ end
19
+
20
+ describe '#repository' do
21
+ it 'returns the repository' do
22
+ subject.repository
23
+ end
24
+
25
+ context 'Github' do
26
+ let(:uri) do
27
+ ElmInstall::Uri::Github('test/repo')
28
+ end
29
+
30
+ it 'returns the repository' do
31
+ subject.repository
32
+ end
33
+ end
34
+ end
35
+
36
+ context 'With repository' do
37
+ before do
38
+ allow(subject)
39
+ .to receive(:repository)
40
+ .and_return(repository)
41
+ end
42
+
43
+ context 'Github' do
44
+ let(:uri) do
45
+ ElmInstall::Uri::Github('test/repo')
46
+ end
47
+
48
+ it 'returns the versions' do
49
+ expect(repository)
50
+ .to receive(:fetch)
51
+
52
+ expect(repository)
53
+ .to receive(:versions)
54
+ .and_return([], [Semverse::Version.new('1.0.0')])
55
+
56
+ subject.versions([])
57
+ end
58
+ end
59
+
60
+ context 'Ssh' do
61
+ describe '#fetch' do
62
+ it 'checks out the given version' do
63
+ expect(repository)
64
+ .to receive(:checkout)
65
+ .with('1.0.0')
66
+ .and_return(Dir.new('.'))
67
+
68
+ subject.fetch(Semverse::Version.new('1.0.0'))
69
+ end
70
+
71
+ context 'With branch' do
72
+ let(:branch) do
73
+ ElmInstall::Branch::Just('test')
74
+ end
75
+
76
+ it 'checkout out the reference' do
77
+ expect(repository)
78
+ .to receive(:checkout)
79
+ .with('test')
80
+ .and_return(Dir.new('.'))
81
+
82
+ subject.fetch(Semverse::Version.new('1.0.0'))
83
+ end
84
+
85
+ describe '#versions' do
86
+ it 'returns the versions' do
87
+ expect(subject)
88
+ .to receive(:identifier)
89
+ .and_return(double(version: Semverse::Version.new('1.0.0')))
90
+
91
+ expect(repository)
92
+ .to receive(:checkout)
93
+ .and_return(Dir.new('.'))
94
+
95
+ subject.versions([])
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ describe '#versions' do
102
+ it 'returns the versions' do
103
+ expect(repository)
104
+ .to receive(:fetch)
105
+
106
+ expect(repository)
107
+ .to receive(:versions)
108
+ .and_return([], [Semverse::Version.new('1.0.0')])
109
+
110
+ subject.versions([])
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,53 @@
1
+ describe ElmInstall::Identifier do
2
+ subject { described_class.new Dir.new('.') }
3
+
4
+ let(:package_json) do
5
+ {
6
+ 'dependencies' =>
7
+ {
8
+ 'test/test' => '1.0.0 <= v < 2.0.0',
9
+ 'test/ref' => '1.0.0 <= v < 2.0.0',
10
+ 'test/dir' => '1.0.0 <= v < 2.0.0'
11
+ },
12
+ 'dependency-sources' =>
13
+ {
14
+ 'test/test' => 'git@github.com:test/test',
15
+ 'test/ref' => {
16
+ url: 'http://www.github.com/test/test.git',
17
+ ref: 'master'
18
+ },
19
+ 'test/dir' => '../'
20
+ },
21
+ version: '1.0.0'
22
+ }.to_json
23
+ end
24
+
25
+ before do
26
+ allow(File)
27
+ .to receive(:read)
28
+ .and_return(package_json)
29
+ end
30
+
31
+ describe 'Invalid json' do
32
+ let(:package_json) { '' }
33
+
34
+ it 'throws an error' do
35
+ expect(ElmInstall::Logger)
36
+ .to receive(:arrow)
37
+ .twice
38
+
39
+ subject
40
+ end
41
+ end
42
+
43
+ describe '#version' do
44
+ it 'returns the version from the json' do
45
+ expect(subject.version(Dir.new('.')))
46
+ .to eq(Semverse::Version.new('1.0.0'))
47
+ end
48
+ end
49
+
50
+ it 'identifies sources and dependencies' do
51
+ subject
52
+ end
53
+ end
@@ -1,71 +1,102 @@
1
- require 'spec_helper'
2
-
3
1
  describe ElmInstall::Installer do
4
2
  subject { described_class.new cache_directory: CACHE_DIRECTORY }
5
3
 
6
4
  let(:main_package) do
7
- { dependencies: { 'base/core' => '1.0.0 <= v < 2.0.0' } }.to_json
5
+ {
6
+ dependencies:
7
+ {
8
+ 'base/core' => '1.0.0 <= v < 2.0.0',
9
+ 'base/uri' => '1.0.0 <= v < 2.0.0',
10
+ 'base/ssh' => '1.0.0 <= v < 2.0.0'
11
+ },
12
+ 'dependency-sources' => {
13
+ 'base/uri' => 'https://github.com/base/uri',
14
+ 'base/ssh' => {
15
+ url: 'git@github.com:base/ssh',
16
+ ref: 'test'
17
+ }
18
+ }
19
+ }.to_json
8
20
  end
9
21
 
10
22
  let(:base_package) do
11
- { dependencies: {} }.to_json
23
+ { dependencies: { 'test/core' => '1.0.0 <= v < 2.0.0' } }.to_json
24
+ end
25
+
26
+ let(:empty_package) do
27
+ {}.to_json
12
28
  end
13
29
 
14
30
  context 'sucessfull install' do
15
31
  before do
16
32
  expect(File)
17
33
  .to receive(:read)
18
- .and_return(main_package, base_package, base_package)
34
+ .with(File.join(Dir.pwd, 'elm-package.json'))
35
+ .and_return(main_package)
36
+ .twice
19
37
 
20
- expect_any_instance_of(ElmInstall::Resolver)
21
- .to receive(:add_constraints)
38
+ expect(File)
39
+ .to receive(:read)
40
+ .with(File.join(Dir.new(CACHE_DIRECTORY), 'elm-package.json'))
41
+ .and_return(base_package, empty_package, empty_package, empty_package)
22
42
 
23
- expect(subject)
24
- .to receive(:puts)
25
- .exactly(4).times
43
+ allow_any_instance_of(ElmInstall::GitSource)
44
+ .to receive(:versions)
45
+ .and_return([Semverse::Version.new('1.0.0')])
26
46
 
27
- expect(File)
28
- .to receive(:binwrite)
29
- .with('spec/fixtures/cache/ref-cache.json', any_args)
47
+ allow_any_instance_of(ElmInstall::GitSource)
48
+ .to receive(:fetch)
49
+ .with(Semverse::Version.new('1.0.0'))
50
+ .and_return Dir.new(CACHE_DIRECTORY)
30
51
 
31
- expect(File)
32
- .to receive(:binwrite)
33
- .with('spec/fixtures/cache/cache.json', any_args)
52
+ expect(ElmInstall::Logger)
53
+ .to receive(:dot)
54
+ .exactly(4).times
55
+
56
+ expect(subject)
57
+ .to receive(:puts)
58
+ .exactly(3).times
34
59
 
35
60
  expect(File)
36
61
  .to receive(:binwrite)
37
62
  .with('elm-stuff/exact-dependencies.json', any_args)
63
+ .and_return(0)
38
64
  end
39
65
 
40
- it 'should install dependencies' do
66
+ it 'installs dependencies' do
41
67
  subject.install
42
68
  end
43
69
  end
44
70
 
45
71
  context 'unsuccessfull install' do
72
+ let(:main_package) do
73
+ { dependencies: { 'base/test' => '1.0.0 <= v < 2.0.0' } }.to_json
74
+ end
75
+
46
76
  before do
47
77
  expect(File)
48
78
  .to receive(:read)
49
- .and_return(main_package, base_package, base_package)
50
-
51
- expect_any_instance_of(ElmInstall::Resolver)
52
- .to receive(:add_constraints)
53
- .exactly(2).times
79
+ .with(File.join(Dir.pwd, 'elm-package.json'))
80
+ .and_return(main_package)
81
+ .twice
54
82
 
55
83
  expect(subject)
56
- .to receive(:populate_elm_stuff)
57
- .exactly(2).times
84
+ .to receive(:results)
58
85
  .and_raise(Solve::Errors::NoSolutionError)
59
86
 
87
+ expect_any_instance_of(ElmInstall::GitSource)
88
+ .to receive(:versions)
89
+ .and_return([])
90
+
60
91
  expect(ElmInstall::Logger)
61
92
  .to receive(:arrow)
62
93
 
63
94
  expect(subject)
64
95
  .to receive(:puts)
65
- .exactly(4).times
96
+ .exactly(2).times
66
97
  end
67
98
 
68
- it 'should install dependencies' do
99
+ it 'does not install anything' do
69
100
  subject.install
70
101
  end
71
102
  end