elm_install 0.3.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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