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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/features/.nav +6 -0
- data/features/branches/README.md +12 -0
- data/features/branches/changing_tracking_branches.feature +78 -0
- data/features/branches/detect_incompatible_declarations.feature +72 -0
- data/features/branches/install.feature +51 -0
- data/features/branches/upgrade.feature +30 -0
- data/features/install_vim_flavor.md +1 -1
- data/features/news.md +10 -0
- data/features/philosophy.md +22 -1
- data/features/resolve_dependencies/basics.feature +0 -32
- data/features/step_definitions/flavor_steps.rb +10 -0
- data/features/support/env.rb +7 -1
- data/features/version_lock.feature +1 -20
- data/features/version_tag_format.feature +44 -8
- data/lib/vim-flavor.rb +2 -0
- data/lib/vim-flavor/branchversion.rb +28 -0
- data/lib/vim-flavor/facade.rb +7 -3
- data/lib/vim-flavor/flavor.rb +20 -5
- data/lib/vim-flavor/flavorfile.rb +13 -12
- data/lib/vim-flavor/lockfileparser.rb +18 -4
- data/lib/vim-flavor/plainversion.rb +28 -0
- data/lib/vim-flavor/version.rb +10 -17
- data/lib/vim-flavor/versionconstraint.rb +23 -7
- data/spec/branchversion_spec.rb +50 -0
- data/spec/enumerableextension_spec.rb +4 -4
- data/spec/facade_spec.rb +2 -2
- data/spec/flavor_spec.rb +9 -8
- data/spec/flavorfile_spec.rb +44 -25
- data/spec/lockfile_spec.rb +58 -23
- data/spec/plainversion_spec.rb +75 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/stringextension_spec.rb +4 -3
- data/spec/version_spec.rb +33 -51
- data/spec/versionconstraint_spec.rb +81 -26
- data/vim-flavor.gemspec +1 -0
- 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 "
|
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 (
|
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 "
|
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
|
data/lib/vim-flavor/facade.rb
CHANGED
@@ -102,10 +102,10 @@ module Vim
|
|
102
102
|
if vs.length == 1
|
103
103
|
nfg.first
|
104
104
|
else
|
105
|
-
|
106
|
-
if nfg.all? {|nf| nf.satisfied_with?(
|
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(
|
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:'
|
data/lib/vim-flavor/flavor.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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(
|
51
|
-
|
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
|
-
|
41
|
-
|
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 =>
|
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 =
|
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
|
data/lib/vim-flavor/version.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
module Vim
|
2
2
|
module Flavor
|
3
|
-
VERSION = '
|
3
|
+
VERSION = '2.0.0'
|
4
4
|
|
5
|
-
class Version
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
22
|
-
|
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
|
-
|
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*(
|
30
|
+
m = /^\s*(>=|~>|branch:)\s+(\S+)\s*$/.match(s)
|
24
31
|
if m
|
25
|
-
|
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?(
|
32
|
-
v = Version.create(other_version_or_s)
|
42
|
+
def compatible?(version)
|
33
43
|
if qualifier == '~>'
|
34
|
-
|
44
|
+
PlainVersion === version and
|
45
|
+
self.base_version.bump() > version and
|
46
|
+
version >= self.base_version
|
35
47
|
elsif qualifier == '>='
|
36
|
-
|
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
|