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