vim-flavor 1.1.5 → 2.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/features/.nav +6 -0
  4. data/features/branches/README.md +12 -0
  5. data/features/branches/changing_tracking_branches.feature +78 -0
  6. data/features/branches/detect_incompatible_declarations.feature +72 -0
  7. data/features/branches/install.feature +51 -0
  8. data/features/branches/upgrade.feature +30 -0
  9. data/features/install_vim_flavor.md +1 -1
  10. data/features/news.md +10 -0
  11. data/features/philosophy.md +22 -1
  12. data/features/resolve_dependencies/basics.feature +0 -32
  13. data/features/step_definitions/flavor_steps.rb +10 -0
  14. data/features/support/env.rb +7 -1
  15. data/features/version_lock.feature +1 -20
  16. data/features/version_tag_format.feature +44 -8
  17. data/lib/vim-flavor.rb +2 -0
  18. data/lib/vim-flavor/branchversion.rb +28 -0
  19. data/lib/vim-flavor/facade.rb +7 -3
  20. data/lib/vim-flavor/flavor.rb +20 -5
  21. data/lib/vim-flavor/flavorfile.rb +13 -12
  22. data/lib/vim-flavor/lockfileparser.rb +18 -4
  23. data/lib/vim-flavor/plainversion.rb +28 -0
  24. data/lib/vim-flavor/version.rb +10 -17
  25. data/lib/vim-flavor/versionconstraint.rb +23 -7
  26. data/spec/branchversion_spec.rb +50 -0
  27. data/spec/enumerableextension_spec.rb +4 -4
  28. data/spec/facade_spec.rb +2 -2
  29. data/spec/flavor_spec.rb +9 -8
  30. data/spec/flavorfile_spec.rb +44 -25
  31. data/spec/lockfile_spec.rb +58 -23
  32. data/spec/plainversion_spec.rb +75 -0
  33. data/spec/spec_helper.rb +10 -0
  34. data/spec/stringextension_spec.rb +4 -3
  35. data/spec/version_spec.rb +33 -51
  36. data/spec/versionconstraint_spec.rb +81 -26
  37. data/vim-flavor.gemspec +1 -0
  38. metadata +35 -3
@@ -3,35 +3,71 @@ Feature: Version tag format
3
3
  as a lazy Vim user,
4
4
  I want to use only tags which are formatted as versions.
5
5
 
6
+ # Points:
7
+ # - Use ~> to check versions are properly compared.
8
+ # - Install twice to check whether a lockfile is properly read or not.
9
+
6
10
  Scenario: With tags in the style of "X.Y.Z"
7
- Given a repository "foo" with versions "1 1.2 1.2.3"
11
+ Given a repository "foo" with versions "1.0 1.1 1.2 1.2.3"
8
12
  And a flavorfile with:
9
13
  """ruby
10
- flavor '$foo_uri'
14
+ flavor '$foo_uri', '~> 1.1'
11
15
  """
12
16
  When I run `vim-flavor install`
13
- Then it should pass
17
+ Then it should pass with template:
18
+ """
19
+ Checking versions...
20
+ Use $foo_uri ... 1.2.3
21
+ Deploying plugins...
22
+ $foo_uri 1.2.3 ... done
23
+ Completed.
24
+ """
14
25
  And a lockfile is created with:
15
26
  """
16
27
  $foo_uri (1.2.3)
17
28
  """
18
29
  And a bootstrap script is created in "$home/.vim"
19
30
  And a flavor "$foo_uri" version "1.2.3" is deployed to "$home/.vim"
31
+ When I run `vim-flavor install`
32
+ Then it should pass with template:
33
+ """
34
+ Checking versions...
35
+ Use $foo_uri ... 1.2.3
36
+ Deploying plugins...
37
+ $foo_uri 1.2.3 ... skipped (already deployed)
38
+ Completed.
39
+ """
20
40
 
21
41
  Scenario: With tags in the style of "vX.Y.Z"
22
- Given a repository "foo" with versions "v4.5.6 v7 v8.9"
42
+ Given a repository "foo" with versions "v1.0 v1.1 v1.2 v1.2.3"
23
43
  And a flavorfile with:
24
44
  """ruby
25
- flavor '$foo_uri'
45
+ flavor '$foo_uri', '~> 1.1'
26
46
  """
27
47
  When I run `vim-flavor install`
28
- Then it should pass
48
+ Then it should pass with template:
49
+ """
50
+ Checking versions...
51
+ Use $foo_uri ... v1.2.3
52
+ Deploying plugins...
53
+ $foo_uri v1.2.3 ... done
54
+ Completed.
55
+ """
29
56
  And a lockfile is created with:
30
57
  """
31
- $foo_uri (v8.9)
58
+ $foo_uri (v1.2.3)
32
59
  """
33
60
  And a bootstrap script is created in "$home/.vim"
34
- And a flavor "$foo_uri" version "v8.9" is deployed to "$home/.vim"
61
+ And a flavor "$foo_uri" version "v1.2.3" is deployed to "$home/.vim"
62
+ When I run `vim-flavor install`
63
+ Then it should pass with template:
64
+ """
65
+ Checking versions...
66
+ Use $foo_uri ... v1.2.3
67
+ Deploying plugins...
68
+ $foo_uri v1.2.3 ... skipped (already deployed)
69
+ Completed.
70
+ """
35
71
 
36
72
  Scenario: Without valid tags
37
73
  Given a repository "foo" with versions "abc def ghi"
data/lib/vim-flavor.rb CHANGED
@@ -4,6 +4,7 @@ require 'vim-flavor/enumerableextension'
4
4
  module Vim
5
5
  module Flavor
6
6
  [
7
+ :BranchVersion,
7
8
  :CLI,
8
9
  :Env,
9
10
  :Facade,
@@ -11,6 +12,7 @@ module Vim
11
12
  :FlavorFile,
12
13
  :LockFile,
13
14
  :LockFileParser,
15
+ :PlainVersion,
14
16
  :ShellUtility,
15
17
  :StringExtension,
16
18
  :VERSION,
@@ -0,0 +1,28 @@
1
+ module Vim
2
+ module Flavor
3
+ class BranchVersion
4
+ attr_reader :branch
5
+ attr_reader :revision
6
+
7
+ def initialize(branch, revision)
8
+ @branch = branch
9
+ @revision = revision
10
+ end
11
+
12
+ def ==(other)
13
+ self.class === other and
14
+ self.branch == other.branch and
15
+ self.revision == other.revision
16
+ end
17
+
18
+ def to_s()
19
+ "#{revision} at #{branch}"
20
+ end
21
+
22
+ def to_revision()
23
+ return revision if revision
24
+ throw "Internal error: A revision of a branch #{branch} is not known"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -102,10 +102,10 @@ module Vim
102
102
  if vs.length == 1
103
103
  nfg.first
104
104
  else
105
- latest_version = vs.max()
106
- if nfg.all? {|nf| nf.satisfied_with?(latest_version)}
105
+ lv = find_latest_version(vs)
106
+ if lv and nfg.all? {|nf| nf.satisfied_with?(lv)}
107
107
  nf = nfg.first
108
- nf.use_specific_version(latest_version)
108
+ nf.use_specific_version(lv)
109
109
  nf
110
110
  else
111
111
  stop_by_incompatible_declarations(nfg)
@@ -113,6 +113,10 @@ module Vim
113
113
  end
114
114
  end
115
115
 
116
+ def find_latest_version(vs)
117
+ vs.all? {|v| PlainVersion === v} and vs.max() or nil
118
+ end
119
+
116
120
  def stop_by_incompatible_declarations(nfg)
117
121
  ss = []
118
122
  ss << 'Found incompatible declarations:'
@@ -28,7 +28,7 @@ module Vim
28
28
  system <<-"END"
29
29
  {
30
30
  cd '#{cached_repo_path}' &&
31
- git rev-list --quiet '#{version}'
31
+ git rev-list --quiet '#{version.to_revision}' --
32
32
  } >/dev/null 2>&1
33
33
  END
34
34
  end
@@ -74,7 +74,7 @@ module Vim
74
74
  sh %Q{
75
75
  {
76
76
  cd '#{cached_repo_path}' &&
77
- git fetch --tags
77
+ git fetch origin --tags 'refs/heads/*:refs/remotes/origin/*'
78
78
  } 2>&1
79
79
  }
80
80
  end
@@ -83,7 +83,7 @@ module Vim
83
83
  sh %Q[
84
84
  {
85
85
  cd '#{cached_repo_path}' &&
86
- git checkout -f '#{locked_version}'
86
+ git checkout -f '#{locked_version.to_revision}'
87
87
  } 2>&1
88
88
  ]
89
89
  end
@@ -93,7 +93,7 @@ module Vim
93
93
  sh %Q[
94
94
  {
95
95
  cd '#{cached_repo_path}' &&
96
- git checkout -f '#{locked_version}' &&
96
+ git checkout -f '#{locked_version.to_revision}' &&
97
97
  git checkout-index -a -f --prefix='#{deployment_path}/' &&
98
98
  {
99
99
  vim -u NONE -i NONE -n -N -e -s -c '
@@ -108,7 +108,14 @@ module Vim
108
108
 
109
109
  def use_appropriate_version()
110
110
  @locked_version =
111
- version_constraint.find_the_best_version(list_versions)
111
+ case
112
+ when PlainVersion === version_constraint.base_version
113
+ version_constraint.find_the_best_version(list_versions)
114
+ when BranchVersion === version_constraint.base_version
115
+ make_branch_version(version_constraint.base_version.branch)
116
+ else
117
+ throw "Unexpected version_constraint: #{version_constraint}"
118
+ end
112
119
  end
113
120
 
114
121
  def use_specific_version(locked_version)
@@ -138,6 +145,14 @@ module Vim
138
145
  def satisfied_with?(version)
139
146
  version_constraint.compatible?(version)
140
147
  end
148
+
149
+ def make_branch_version(branch)
150
+ revision = sh(%Q[
151
+ cd '#{cached_repo_path}' &&
152
+ git rev-list -n1 'origin/#{branch}' --
153
+ ]).chomp
154
+ BranchVersion.new(branch, revision)
155
+ end
141
156
  end
142
157
  end
143
158
  end
@@ -33,22 +33,23 @@ module Vim
33
33
  )
34
34
  end
35
35
 
36
- # :call-seq:
37
- # flavor repo_name, version_constraint='>= 0', options={} -> a_flavor
38
- def flavor(repo_name, *args)
39
- a = args.shift()
40
- if a.kind_of?(String)
41
- version_constraint = a
42
- a = args.shift()
43
- else
44
- version_constraint = '>= 0'
36
+ def flavor(repo_name, version_constraint=nil, group: nil, branch: nil)
37
+ if version_constraint and branch
38
+ throw <<-"END"
39
+ Found an invalid declaration on #{repo_name}.
40
+ A version constraint '#{version_constraint}' and
41
+ a branch '#{branch}' are specified at the same time.
42
+ But a branch cannot be used with a version constraint.
43
+ END
45
44
  end
46
- options = a.kind_of?(Hash) ? a : {}
47
45
 
48
46
  f = Flavor.new()
49
47
  f.repo_name = repo_name
50
- f.version_constraint = VersionConstraint.new(version_constraint)
51
- f.group = options[:group] || default_group
48
+ f.version_constraint = VersionConstraint.new(
49
+ branch && "branch: #{branch}" ||
50
+ version_constraint || '>= 0'
51
+ )
52
+ f.group = group || default_group
52
53
  flavor_table[f.repo_name] = f
53
54
  end
54
55
 
@@ -37,10 +37,19 @@ module Vim
37
37
  }
38
38
  rule(:locked_version) {
39
39
  (
40
- str('v').maybe >>
41
- match('[\d.]').repeat(1)
40
+ branch_version |
41
+ plain_version
42
42
  ).as(:locked_version)
43
43
  }
44
+ rule(:plain_version) {
45
+ str('v').maybe >>
46
+ match('[\d.]').repeat(1)
47
+ }
48
+ rule(:branch_version) {
49
+ match('\h').repeat(1).as(:revision) >>
50
+ str(' at ') >>
51
+ match('[^\s()]').repeat(1).as(:branch)
52
+ }
44
53
 
45
54
  rule(:space) {match('[ \t]').repeat(1)}
46
55
  rule(:space?) {space.maybe}
@@ -52,12 +61,17 @@ module Vim
52
61
  rule(
53
62
  :flavor => {
54
63
  :repo_name => simple(:repo_name),
55
- :locked_version => simple(:locked_version),
64
+ :locked_version => subtree(:locked_version),
56
65
  }
57
66
  ) {
58
67
  f = Flavor.new()
59
68
  f.repo_name = repo_name.to_s
60
- f.locked_version = Version.create(locked_version.to_s)
69
+ f.locked_version =
70
+ Version.create(
71
+ Hash === locked_version ?
72
+ locked_version :
73
+ locked_version.to_s
74
+ )
61
75
  f
62
76
  }
63
77
  end
@@ -0,0 +1,28 @@
1
+ module Vim
2
+ module Flavor
3
+ class PlainVersion < Gem::Version
4
+ attr_accessor :original_tag_name
5
+
6
+ def initialize(tag_name)
7
+ @original_tag_name = tag_name
8
+ super(self.class.normalize_tag_name(tag_name))
9
+ end
10
+
11
+ def self.normalize_tag_name(tag_name)
12
+ tag_name.to_s.sub(/^v/, '')
13
+ end
14
+
15
+ def self.correct?(tag_name)
16
+ super(normalize_tag_name(tag_name))
17
+ end
18
+
19
+ def to_s()
20
+ @original_tag_name
21
+ end
22
+
23
+ def to_revision()
24
+ to_s
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,25 +1,18 @@
1
1
  module Vim
2
2
  module Flavor
3
- VERSION = '1.1.5'
3
+ VERSION = '2.0.0'
4
4
 
5
- class Version < Gem::Version
6
- attr_accessor :original_tag_name
7
-
8
- def initialize(tag_name)
9
- @original_tag_name = tag_name
10
- super(self.class.normalize_tag_name(tag_name))
11
- end
12
-
13
- def self.normalize_tag_name(tag_name)
14
- tag_name.to_s.sub(/^v/, '')
15
- end
16
-
17
- def self.correct?(tag_name)
18
- super(normalize_tag_name(tag_name))
5
+ class Version
6
+ def self.create(arg)
7
+ if String === arg
8
+ PlainVersion.create(arg)
9
+ else
10
+ BranchVersion.new(arg[:branch], arg[:revision])
11
+ end
19
12
  end
20
13
 
21
- def to_s()
22
- @original_tag_name
14
+ def self.correct?(*args)
15
+ PlainVersion.correct?(*args)
23
16
  end
24
17
  end
25
18
  end
@@ -11,7 +11,14 @@ module Vim
11
11
  end
12
12
 
13
13
  def to_s()
14
- "#{qualifier} #{base_version}"
14
+ case
15
+ when PlainVersion === base_version
16
+ "#{qualifier} #{base_version}"
17
+ when BranchVersion === base_version
18
+ "#{qualifier} #{base_version.branch}"
19
+ else
20
+ throw "Unexpected base_version: #{base_version}"
21
+ end
15
22
  end
16
23
 
17
24
  def ==(other)
@@ -20,20 +27,29 @@ module Vim
20
27
  end
21
28
 
22
29
  def self.parse(s)
23
- m = /^\s*(>=|~>)\s+(\S+)$/.match(s)
30
+ m = /^\s*(>=|~>|branch:)\s+(\S+)\s*$/.match(s)
24
31
  if m
25
- [Version.create(m[2]), m[1]]
32
+ if m[1] == 'branch:'
33
+ [Version.create(branch: m[2]), m[1]]
34
+ else
35
+ [Version.create(m[2]), m[1]]
36
+ end
26
37
  else
27
38
  raise "Invalid version constraint: #{s.inspect}"
28
39
  end
29
40
  end
30
41
 
31
- def compatible?(other_version_or_s)
32
- v = Version.create(other_version_or_s)
42
+ def compatible?(version)
33
43
  if qualifier == '~>'
34
- self.base_version.bump() > v and v >= self.base_version
44
+ PlainVersion === version and
45
+ self.base_version.bump() > version and
46
+ version >= self.base_version
35
47
  elsif qualifier == '>='
36
- v >= self.base_version
48
+ PlainVersion === version and
49
+ version >= self.base_version
50
+ elsif qualifier == 'branch:'
51
+ BranchVersion === version and
52
+ version.branch == self.base_version.branch
37
53
  else
38
54
  raise NotImplementedError
39
55
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Vim
4
+ module Flavor
5
+ describe BranchVersion do
6
+ def v(*args)
7
+ described_class.new(*args)
8
+ end
9
+
10
+ let(:v1) {v('master', '1' * 40)}
11
+ let(:v1d) {v('master', '1' * 40)}
12
+ let(:v2) {v('master', '2' * 40)}
13
+
14
+ it 'is equatable' do
15
+ expect(v1).to be == v1
16
+ expect(v1).to be == v1d
17
+ expect(v1).not_to be == v2
18
+ end
19
+
20
+ it 'is not comparable' do
21
+ expect {v1 < v2}.to raise_error
22
+ expect {v1 <= v2}.to raise_error
23
+ expect {v1 > v2}.to raise_error
24
+ expect {v1 >= v2}.to raise_error
25
+ expect(v1 <=> v2).to be_nil
26
+ end
27
+
28
+ describe '#to_s' do
29
+ it 'makes a user-friendly representation' do
30
+ expect(v1.to_s).to be == "#{'1' * 40} at master"
31
+ end
32
+ end
33
+
34
+ describe '#to_revision' do
35
+ it 'returns a revision corresponding to a branch' do
36
+ expect(v('master', '1' * 40).to_revision).to be == '1' * 40
37
+ expect(v('experimental', '2' * 40).to_revision).to be == '2' * 40
38
+ end
39
+
40
+ it 'fails if a revision is not known' do
41
+ expect {
42
+ v('master', nil).to_revision
43
+ }.to raise_error(
44
+ /Internal error: A revision of a branch master is not known/
45
+ )
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end