vim-flavor 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -28,6 +28,50 @@
28
28
  gem install vim-flavor
29
29
 
30
30
 
31
+ ### Installable plugins
32
+
33
+ Not all Vim plugins can be installed with vim-flavor.
34
+ vim-flavor can install plugins which meet the following conditions:
35
+
36
+ * Plugins must have dedicated Git repositories.
37
+ vim-flavor does not support other version control systems.
38
+ This is an intentional design. Because:
39
+ * [vim-scripts.org](http://vim-scripts.org/) provides
40
+ [a comprehensive Git mirrors](https://github.com/vim-scripts) for
41
+ [plugins uploaded to www.vim.org](http://www.vim.org/scripts/index.php).
42
+ * Experimental plugins which are not uploaded to www.vim.org
43
+ are usually found in [GitHub](https://github.com/).
44
+ * Plugins must follow [the versioning pocilies of
45
+ RubyGems](http://docs.rubygems.org/read/chapter/7#page26) and have "version"
46
+ tags in their repositories. For example, if there is the version 1.2.3 of
47
+ a plugin, its repository must have the tag `1.2.3`, and the files of the
48
+ version 1.2.3 can be checked out via the tag `1.2.3`. In other words,
49
+ plugins which do not have proper tags are not installabe.
50
+ This is an intentional design. Because:
51
+ * It's not possible to determine whether two versions are compatible or not
52
+ without "version" tags. Compatibility is a big problem to resolve
53
+ dependencies of plugins. For example, if plugin A requires plugin X 1.2.3
54
+ or later while plugin B requires plugin X 2.0 or later, it's not possible
55
+ to use A and B at the same time. Such problems should be detected before
56
+ installing plugins.
57
+ * Git mirrors by vim-scripts.org are tagged with version numbers.
58
+ * Some Git repositories might not have "version" tags.
59
+ Such plugins are not ready to use for everyone.
60
+ So that it should not be installable.
61
+ * Plugins must have proper directory structures.
62
+ For example, directories such as `autoload`, `syntax` etc should exist in
63
+ the roots of plugins.
64
+ This is an intentional design. Because:
65
+ * Git mirrors by vim-scripts.org have proper directory structures even if
66
+ the original plugins are uploaded to www.vim.org without proper directory
67
+ structures. (A good example is
68
+ [a.vim](http://www.vim.org/scripts/script.php?script_id=31) and
69
+ [its mirror](https://github.com/vim-scripts/a.vim).)
70
+ * Other Git repositoris might not have proper directory structures.
71
+ Such plugins are not ready to use for everyone.
72
+ So that it should not be installable.
73
+
74
+
31
75
 
32
76
 
33
77
  ## Typical usage
data/lib/vim-flavor.rb CHANGED
@@ -1,66 +1,24 @@
1
1
  require 'bundler/setup'
2
- require 'fileutils'
3
- require 'thor'
4
- require 'vim-flavor/version'
5
- require 'yaml'
6
2
 
7
3
  module Vim
8
4
  module Flavor
9
- module StringExtension
10
- def to_flavors_path()
11
- "#{self}/flavors"
12
- end
5
+ [
6
+ :CLI,
7
+ :Facade,
8
+ :Flavor,
9
+ :FlavorFile,
10
+ :LockFile,
11
+ :StringExtension,
12
+ :VERSION,
13
+ :VersionConstraint,
14
+ ].each do |name|
15
+ autoload name, "vim-flavor/#{name.to_s().downcase()}"
13
16
  end
14
17
 
15
18
  class ::String
16
19
  include StringExtension
17
20
  end
18
21
 
19
- class VersionConstraint
20
- attr_reader :base_version, :operator
21
-
22
- def initialize(s)
23
- @base_version, @operator = parse(s)
24
- end
25
-
26
- def to_s()
27
- "#{@operator} #{@base_version}"
28
- end
29
-
30
- def ==(other)
31
- self.base_version == other.base_version &&
32
- self.operator == other.operator
33
- end
34
-
35
- def parse(s)
36
- m = /^\s*(>=|~>)\s+(\S+)$/.match(s)
37
- if m then
38
- [Gem::Version.create(m[2]), m[1]]
39
- else
40
- raise "Invalid version constraint: #{s.inspect}"
41
- end
42
- end
43
-
44
- def compatible?(other_version_or_s)
45
- v = Gem::Version.create(other_version_or_s)
46
- if @operator == '~>' then
47
- self.base_version.bump() > v and v >= self.base_version
48
- elsif @operator == '>=' then
49
- v >= self.base_version
50
- else
51
- raise NotImplementedError
52
- end
53
- end
54
-
55
- def find_the_best_version(versions)
56
- versions.
57
- select {|v| compatible?(v)}.
58
- sort().
59
- reverse().
60
- first
61
- end
62
- end
63
-
64
22
  class << self
65
23
  @@dot_path = File.expand_path('~/.vim-flavor')
66
24
 
@@ -72,414 +30,5 @@ module Vim
72
30
  @@dot_path = path
73
31
  end
74
32
  end
75
-
76
- class Flavor
77
- @@properties = [
78
- :groups,
79
- :locked_version,
80
- :repo_name,
81
- :repo_uri,
82
- :version_contraint,
83
- ]
84
-
85
- @@properties.each do |p|
86
- attr_accessor p
87
- end
88
-
89
- def initialize()
90
- @groups = []
91
- end
92
-
93
- def ==(other)
94
- return false if self.class != other.class
95
- @@properties.all? do |p|
96
- self.send(p) == other.send(p)
97
- end
98
- end
99
-
100
- def zapped_repo_dir_name
101
- @repo_name.gsub(/[^A-Za-z0-9._-]/, '_')
102
- end
103
-
104
- def cached_repo_path
105
- @cached_repo_path ||=
106
- "#{Vim::Flavor.dot_path}/repos/#{zapped_repo_dir_name}"
107
- end
108
-
109
- def make_deploy_path(vimfiles_path)
110
- "#{vimfiles_path.to_flavors_path()}/#{zapped_repo_dir_name}"
111
- end
112
-
113
- def clone()
114
- message = %x[
115
- {
116
- git clone '#{@repo_uri}' '#{cached_repo_path}'
117
- } 2>&1
118
- ]
119
- if $? != 0 then
120
- raise RuntimeError, message
121
- end
122
- true
123
- end
124
-
125
- def fetch()
126
- message = %x[
127
- {
128
- cd #{cached_repo_path.inspect} &&
129
- git fetch origin
130
- } 2>&1
131
- ]
132
- if $? != 0 then
133
- raise RuntimeError, message
134
- end
135
- end
136
-
137
- def deploy(vimfiles_path)
138
- deploy_path = make_deploy_path(vimfiles_path)
139
- message = %x[
140
- {
141
- cd '#{cached_repo_path}' &&
142
- git checkout -f #{locked_version.inspect} &&
143
- git checkout-index -a -f --prefix='#{deploy_path}/' &&
144
- {
145
- vim -u NONE -i NONE -n -N -e -s -c '
146
- silent! helptags #{deploy_path}/doc
147
- qall!
148
- ' || true
149
- }
150
- } 2>&1
151
- ]
152
- if $? != 0 then
153
- raise RuntimeError, message
154
- end
155
- end
156
-
157
- def undeploy(vimfiles_path)
158
- deploy_path = make_deploy_path(vimfiles_path)
159
- message = %x[
160
- {
161
- rm -fr '#{deploy_path}'
162
- } 2>&1
163
- ]
164
- if $? != 0 then
165
- raise RuntimeError, message
166
- end
167
- end
168
-
169
- def list_versions()
170
- tags = %x[
171
- {
172
- cd '#{cached_repo_path}' &&
173
- git tag
174
- } 2>&1
175
- ]
176
- if $? != 0 then
177
- raise RuntimeError, message
178
- end
179
-
180
- tags.
181
- split(/[\r\n]/).
182
- select {|t| t != ''}.
183
- map {|t| Gem::Version.create(t)}
184
- end
185
-
186
- def update_locked_version()
187
- @locked_version =
188
- version_contraint.find_the_best_version(list_versions())
189
- end
190
- end
191
-
192
- class FlavorFile
193
- attr_reader :flavors
194
-
195
- def initialize()
196
- @flavors = {}
197
- @default_groups = [:default]
198
- end
199
-
200
- def interpret(&block)
201
- instance_eval(&block)
202
- end
203
-
204
- def eval_flavorfile(flavorfile_path)
205
- content = File.open(flavorfile_path, 'rb') do |f|
206
- f.read()
207
- end
208
- interpret do
209
- instance_eval(content)
210
- end
211
- end
212
-
213
- def repo_uri_from_repo_name(repo_name)
214
- if /^([^\/]+)$/.match(repo_name) then
215
- m = Regexp.last_match
216
- "git://github.com/vim-scripts/#{m[1]}.git"
217
- elsif /^([A-Za-z0-9_-]+)\/(.*)$/.match(repo_name) then
218
- m = Regexp.last_match
219
- "git://github.com/#{m[1]}/#{m[2]}.git"
220
- elsif /^[a-z]+:\/\/.*$/.match(repo_name) then
221
- repo_name
222
- else
223
- raise "repo_name is written in invalid format: #{repo_name.inspect}"
224
- end
225
- end
226
-
227
- def flavor(repo_name, *args)
228
- options = Hash === args.last ? args.pop : {}
229
- options[:groups] ||= []
230
- version_contraint = VersionConstraint.new(args.last || '>= 0')
231
-
232
- f = Flavor.new()
233
- f.repo_name = repo_name
234
- f.repo_uri = repo_uri_from_repo_name(repo_name)
235
- f.version_contraint = version_contraint
236
- f.groups = @default_groups + options[:groups]
237
-
238
- @flavors[f.repo_uri] = f
239
- end
240
-
241
- def group(*group_names, &block)
242
- @default_groups.concat(group_names)
243
- yield
244
- ensure
245
- group_names.each do
246
- @default_groups.pop()
247
- end
248
- end
249
- end
250
-
251
- class LockFile
252
- # TODO: Resolve dependencies recursively.
253
-
254
- attr_reader :flavors, :path
255
-
256
- def initialize(path)
257
- @flavors = {} # repo_uri => flavor
258
- @path = path
259
- end
260
-
261
- def load()
262
- h = File.open(@path, 'rb') do |f|
263
- YAML.load(f.read())
264
- end
265
-
266
- @flavors = self.class.flavors_from_poro(h[:flavors])
267
- end
268
-
269
- def save()
270
- h = {}
271
-
272
- h[:flavors] = self.class.poro_from_flavors(@flavors)
273
-
274
- File.open(@path, 'wb') do |f|
275
- YAML.dump(h, f)
276
- end
277
- end
278
-
279
- def self.poro_from_flavors(flavors)
280
- Hash[
281
- flavors.values.map {|f|
282
- [
283
- f.repo_uri,
284
- {
285
- :groups => f.groups,
286
- :locked_version => f.locked_version.to_s(),
287
- :repo_name => f.repo_name,
288
- :version_contraint => f.version_contraint.to_s(),
289
- }
290
- ]
291
- }
292
- ]
293
- end
294
-
295
- def self.flavors_from_poro(poro)
296
- Hash[
297
- poro.to_a().map {|repo_uri, h|
298
- f = Flavor.new()
299
- f.groups = h[:groups]
300
- f.locked_version = Gem::Version.create(h[:locked_version])
301
- f.repo_name = h[:repo_name]
302
- f.repo_uri = repo_uri
303
- f.version_contraint = VersionConstraint.new(h[:version_contraint])
304
- [f.repo_uri, f]
305
- }
306
- ]
307
- end
308
- end
309
-
310
- class Facade
311
- attr_reader :flavorfile
312
- attr_accessor :flavorfile_path
313
- attr_reader :lockfile
314
- attr_accessor :lockfile_path
315
- attr_accessor :traced
316
-
317
- def initialize()
318
- @flavorfile = nil # FlavorFile
319
- @flavorfile_path = "#{Dir.getwd()}/VimFlavor"
320
- @lockfile = nil # LockFile
321
- @lockfile_path = "#{Dir.getwd()}/VimFlavor.lock"
322
- @traced = false
323
- end
324
-
325
- def trace(message)
326
- print(message) if @traced
327
- end
328
-
329
- def load()
330
- @flavorfile = FlavorFile.new()
331
- @flavorfile.eval_flavorfile(@flavorfile_path)
332
-
333
- @lockfile = LockFile.new(@lockfile_path)
334
- @lockfile.load() if File.exists?(@lockfile_path)
335
- end
336
-
337
- def make_new_flavors(current_flavors, locked_flavors, mode)
338
- new_flavors = {}
339
-
340
- current_flavors.each do |repo_uri, cf|
341
- lf = locked_flavors[repo_uri]
342
- nf = cf.dup()
343
-
344
- nf.locked_version =
345
- if (not lf) or
346
- cf.version_contraint != lf.version_contraint or
347
- mode == :update then
348
- cf.locked_version
349
- else
350
- lf.locked_version
351
- end
352
-
353
- new_flavors[repo_uri] = nf
354
- end
355
-
356
- new_flavors
357
- end
358
-
359
- def create_vim_script_for_bootstrap(vimfiles_path)
360
- bootstrap_path = "#{vimfiles_path.to_flavors_path()}/bootstrap.vim"
361
- FileUtils.mkdir_p(File.dirname(bootstrap_path))
362
- File.open(bootstrap_path, 'w') do |f|
363
- f.write(<<-'END')
364
- function! s:bootstrap()
365
- let current_rtp = &runtimepath
366
- let current_rtps = split(current_rtp, ',')
367
- set runtimepath&
368
- let default_rtp = &runtimepath
369
- let default_rtps = split(default_rtp, ',')
370
- let user_dir = default_rtps[0]
371
- let user_after_dir = default_rtps[-1]
372
- let base_rtps =
373
- \ filter(copy(current_rtps),
374
- \ 'v:val !=# user_dir && v:val !=# user_after_dir')
375
- let flavor_dirs =
376
- \ filter(split(glob(user_dir . '/flavors/*'), '\n'),
377
- \ 'isdirectory(v:val)')
378
- let new_rtps =
379
- \ []
380
- \ + [user_dir]
381
- \ + flavor_dirs
382
- \ + base_rtps
383
- \ + map(reverse(copy(flavor_dirs)), 'v:val . "/after"')
384
- \ + [user_after_dir]
385
- let &runtimepath = join(new_rtps, ',')
386
- endfunction
387
-
388
- call s:bootstrap()
389
- END
390
- end
391
- end
392
-
393
- def deploy_flavors(flavor_list, vimfiles_path)
394
- FileUtils.rm_rf(
395
- ["#{vimfiles_path.to_flavors_path()}"],
396
- :secure => true
397
- )
398
-
399
- create_vim_script_for_bootstrap(vimfiles_path)
400
- flavor_list.each do |f|
401
- trace("Deploying #{f.repo_name} (#{f.locked_version})\n")
402
- f.deploy(vimfiles_path)
403
- end
404
- end
405
-
406
- def save_lockfile()
407
- @lockfile.save()
408
- end
409
-
410
- def complete_locked_flavors(mode)
411
- nfs = {}
412
- @flavorfile.flavors.each do |repo_uri, cf|
413
- nf = cf.dup()
414
- lf = @lockfile.flavors[repo_uri]
415
-
416
- trace("Using #{nf.repo_name} ... ")
417
- begin
418
- if not File.exists?(nf.cached_repo_path)
419
- nf.clone()
420
- end
421
-
422
- if mode == :upgrade_all or
423
- (not lf) or
424
- nf.version_contraint != lf.version_contraint then
425
- nf.fetch()
426
- nf.update_locked_version()
427
- else
428
- nf.locked_version = lf.locked_version
429
- end
430
- end
431
- trace("(#{nf.locked_version})\n")
432
-
433
- nfs[repo_uri] = nf
434
- end
435
-
436
- @lockfile.instance_eval do
437
- @flavors = nfs
438
- end
439
- end
440
-
441
- def get_default_vimfiles_path()
442
- # FIXME: Compute more appropriate value.
443
- "#{ENV['HOME']}/.vim"
444
- end
445
-
446
- def install(vimfiles_path)
447
- load()
448
- complete_locked_flavors(:upgrade_if_necessary)
449
- save_lockfile()
450
- deploy_flavors(lockfile.flavors.values, vimfiles_path)
451
- end
452
-
453
- def upgrade(vimfiles_path)
454
- load()
455
- complete_locked_flavors(:upgrade_all)
456
- save_lockfile()
457
- deploy_flavors(lockfile.flavors.values, vimfiles_path)
458
- end
459
- end
460
-
461
- class CLI < Thor
462
- desc 'install', 'Install Vim plugins according to VimFlavor file.'
463
- method_option :vimfiles_path,
464
- :desc => 'A path to your vimfiles directory.'
465
- def install()
466
- facade = Facade.new()
467
- facade.traced = true
468
- facade.install(
469
- options[:vimfiles_path] || facade.get_default_vimfiles_path()
470
- )
471
- end
472
-
473
- desc 'upgrade', 'Upgrade Vim plugins according to VimFlavor file.'
474
- method_option :vimfiles_path,
475
- :desc => 'A path to your vimfiles directory.'
476
- def upgrade()
477
- facade = Facade.new()
478
- facade.traced = true
479
- facade.upgrade(
480
- options[:vimfiles_path] || facade.get_default_vimfiles_path()
481
- )
482
- end
483
- end
484
33
  end
485
34
  end
@@ -0,0 +1,29 @@
1
+ require 'thor'
2
+
3
+ module Vim
4
+ module Flavor
5
+ class CLI < Thor
6
+ desc 'install', 'Install Vim plugins according to VimFlavor file.'
7
+ method_option :vimfiles_path,
8
+ :desc => 'A path to your vimfiles directory.'
9
+ def install()
10
+ facade = Facade.new()
11
+ facade.traced = true
12
+ facade.install(
13
+ options[:vimfiles_path] || facade.get_default_vimfiles_path()
14
+ )
15
+ end
16
+
17
+ desc 'upgrade', 'Upgrade Vim plugins according to VimFlavor file.'
18
+ method_option :vimfiles_path,
19
+ :desc => 'A path to your vimfiles directory.'
20
+ def upgrade()
21
+ facade = Facade.new()
22
+ facade.traced = true
23
+ facade.upgrade(
24
+ options[:vimfiles_path] || facade.get_default_vimfiles_path()
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,156 @@
1
+ require 'fileutils'
2
+
3
+ module Vim
4
+ module Flavor
5
+ class Facade
6
+ attr_reader :flavorfile
7
+ attr_accessor :flavorfile_path
8
+ attr_reader :lockfile
9
+ attr_accessor :lockfile_path
10
+ attr_accessor :traced
11
+
12
+ def initialize()
13
+ @flavorfile = nil # FlavorFile
14
+ @flavorfile_path = "#{Dir.getwd()}/VimFlavor"
15
+ @lockfile = nil # LockFile
16
+ @lockfile_path = "#{Dir.getwd()}/VimFlavor.lock"
17
+ @traced = false
18
+ end
19
+
20
+ def trace(message)
21
+ print(message) if @traced
22
+ end
23
+
24
+ def load()
25
+ @flavorfile = FlavorFile.new()
26
+ @flavorfile.eval_flavorfile(@flavorfile_path)
27
+
28
+ @lockfile = LockFile.new(@lockfile_path)
29
+ @lockfile.load() if File.exists?(@lockfile_path)
30
+ end
31
+
32
+ def make_new_flavors(current_flavors, locked_flavors, mode)
33
+ new_flavors = {}
34
+
35
+ current_flavors.each do |repo_uri, cf|
36
+ lf = locked_flavors[repo_uri]
37
+ nf = cf.dup()
38
+
39
+ nf.locked_version =
40
+ if (not lf) or
41
+ cf.version_contraint != lf.version_contraint or
42
+ mode == :update then
43
+ cf.locked_version
44
+ else
45
+ lf.locked_version
46
+ end
47
+
48
+ new_flavors[repo_uri] = nf
49
+ end
50
+
51
+ new_flavors
52
+ end
53
+
54
+ def create_vim_script_for_bootstrap(vimfiles_path)
55
+ bootstrap_path = "#{vimfiles_path.to_flavors_path()}/bootstrap.vim"
56
+ FileUtils.mkdir_p(File.dirname(bootstrap_path))
57
+ File.open(bootstrap_path, 'w') do |f|
58
+ f.write(<<-'END')
59
+ function! s:bootstrap()
60
+ let current_rtp = &runtimepath
61
+ let current_rtps = split(current_rtp, ',')
62
+ set runtimepath&
63
+ let default_rtp = &runtimepath
64
+ let default_rtps = split(default_rtp, ',')
65
+ let user_dir = default_rtps[0]
66
+ let user_after_dir = default_rtps[-1]
67
+ let base_rtps =
68
+ \ filter(copy(current_rtps),
69
+ \ 'v:val !=# user_dir && v:val !=# user_after_dir')
70
+ let flavor_dirs =
71
+ \ filter(split(glob(user_dir . '/flavors/*'), '\n'),
72
+ \ 'isdirectory(v:val)')
73
+ let new_rtps =
74
+ \ []
75
+ \ + [user_dir]
76
+ \ + flavor_dirs
77
+ \ + base_rtps
78
+ \ + map(reverse(copy(flavor_dirs)), 'v:val . "/after"')
79
+ \ + [user_after_dir]
80
+ let &runtimepath = join(new_rtps, ',')
81
+ endfunction
82
+
83
+ call s:bootstrap()
84
+ END
85
+ end
86
+ end
87
+
88
+ def deploy_flavors(flavor_list, vimfiles_path)
89
+ FileUtils.rm_rf(
90
+ ["#{vimfiles_path.to_flavors_path()}"],
91
+ :secure => true
92
+ )
93
+
94
+ create_vim_script_for_bootstrap(vimfiles_path)
95
+ flavor_list.each do |f|
96
+ trace("Deploying #{f.repo_name} (#{f.locked_version})\n")
97
+ f.deploy(vimfiles_path)
98
+ end
99
+ end
100
+
101
+ def save_lockfile()
102
+ @lockfile.save()
103
+ end
104
+
105
+ def complete_locked_flavors(mode)
106
+ nfs = {}
107
+ @flavorfile.flavors.each do |repo_uri, cf|
108
+ nf = cf.dup()
109
+ lf = @lockfile.flavors[repo_uri]
110
+
111
+ trace("Using #{nf.repo_name} ... ")
112
+ begin
113
+ if not File.exists?(nf.cached_repo_path)
114
+ nf.clone()
115
+ end
116
+
117
+ if mode == :upgrade_all or
118
+ (not lf) or
119
+ nf.version_contraint != lf.version_contraint then
120
+ nf.fetch()
121
+ nf.update_locked_version()
122
+ else
123
+ nf.locked_version = lf.locked_version
124
+ end
125
+ end
126
+ trace("(#{nf.locked_version})\n")
127
+
128
+ nfs[repo_uri] = nf
129
+ end
130
+
131
+ @lockfile.instance_eval do
132
+ @flavors = nfs
133
+ end
134
+ end
135
+
136
+ def get_default_vimfiles_path()
137
+ # FIXME: Compute more appropriate value.
138
+ "#{ENV['HOME']}/.vim"
139
+ end
140
+
141
+ def install(vimfiles_path)
142
+ load()
143
+ complete_locked_flavors(:upgrade_if_necessary)
144
+ save_lockfile()
145
+ deploy_flavors(lockfile.flavors.values, vimfiles_path)
146
+ end
147
+
148
+ def upgrade(vimfiles_path)
149
+ load()
150
+ complete_locked_flavors(:upgrade_all)
151
+ save_lockfile()
152
+ deploy_flavors(lockfile.flavors.values, vimfiles_path)
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,119 @@
1
+ module Vim
2
+ module Flavor
3
+ class Flavor
4
+ @@properties = [
5
+ :groups,
6
+ :locked_version,
7
+ :repo_name,
8
+ :repo_uri,
9
+ :version_contraint,
10
+ ]
11
+
12
+ @@properties.each do |p|
13
+ attr_accessor p
14
+ end
15
+
16
+ def initialize()
17
+ @groups = []
18
+ end
19
+
20
+ def ==(other)
21
+ return false if self.class != other.class
22
+ @@properties.all? do |p|
23
+ self.send(p) == other.send(p)
24
+ end
25
+ end
26
+
27
+ def zapped_repo_dir_name
28
+ @repo_name.gsub(/[^A-Za-z0-9._-]/, '_')
29
+ end
30
+
31
+ def cached_repo_path
32
+ @cached_repo_path ||=
33
+ "#{Vim::Flavor.dot_path}/repos/#{zapped_repo_dir_name}"
34
+ end
35
+
36
+ def make_deploy_path(vimfiles_path)
37
+ "#{vimfiles_path.to_flavors_path()}/#{zapped_repo_dir_name}"
38
+ end
39
+
40
+ def clone()
41
+ message = %x[
42
+ {
43
+ git clone '#{@repo_uri}' '#{cached_repo_path}'
44
+ } 2>&1
45
+ ]
46
+ if $? != 0 then
47
+ raise RuntimeError, message
48
+ end
49
+ true
50
+ end
51
+
52
+ def fetch()
53
+ message = %x[
54
+ {
55
+ cd #{cached_repo_path.inspect} &&
56
+ git fetch origin
57
+ } 2>&1
58
+ ]
59
+ if $? != 0 then
60
+ raise RuntimeError, message
61
+ end
62
+ end
63
+
64
+ def deploy(vimfiles_path)
65
+ deploy_path = make_deploy_path(vimfiles_path)
66
+ message = %x[
67
+ {
68
+ cd '#{cached_repo_path}' &&
69
+ git checkout -f '#{locked_version}' &&
70
+ git checkout-index -a -f --prefix='#{deploy_path}/' &&
71
+ {
72
+ vim -u NONE -i NONE -n -N -e -s -c '
73
+ silent! helptags #{deploy_path}/doc
74
+ qall!
75
+ ' || true
76
+ }
77
+ } 2>&1
78
+ ]
79
+ if $? != 0 then
80
+ raise RuntimeError, message
81
+ end
82
+ end
83
+
84
+ def undeploy(vimfiles_path)
85
+ deploy_path = make_deploy_path(vimfiles_path)
86
+ message = %x[
87
+ {
88
+ rm -fr '#{deploy_path}'
89
+ } 2>&1
90
+ ]
91
+ if $? != 0 then
92
+ raise RuntimeError, message
93
+ end
94
+ end
95
+
96
+ def list_versions()
97
+ tags = %x[
98
+ {
99
+ cd '#{cached_repo_path}' &&
100
+ git tag
101
+ } 2>&1
102
+ ]
103
+ if $? != 0 then
104
+ raise RuntimeError, message
105
+ end
106
+
107
+ tags.
108
+ split(/[\r\n]/).
109
+ select {|t| t != ''}.
110
+ map {|t| Gem::Version.create(t)}
111
+ end
112
+
113
+ def update_locked_version()
114
+ @locked_version =
115
+ version_contraint.find_the_best_version(list_versions())
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,62 @@
1
+ module Vim
2
+ module Flavor
3
+ class FlavorFile
4
+ attr_reader :flavors
5
+
6
+ def initialize()
7
+ @flavors = {}
8
+ @default_groups = [:default]
9
+ end
10
+
11
+ def interpret(&block)
12
+ instance_eval(&block)
13
+ end
14
+
15
+ def eval_flavorfile(flavorfile_path)
16
+ content = File.open(flavorfile_path, 'rb') do |f|
17
+ f.read()
18
+ end
19
+ interpret do
20
+ instance_eval(content)
21
+ end
22
+ end
23
+
24
+ def repo_uri_from_repo_name(repo_name)
25
+ if /^([^\/]+)$/.match(repo_name) then
26
+ m = Regexp.last_match
27
+ "git://github.com/vim-scripts/#{m[1]}.git"
28
+ elsif /^([A-Za-z0-9_-]+)\/(.*)$/.match(repo_name) then
29
+ m = Regexp.last_match
30
+ "git://github.com/#{m[1]}/#{m[2]}.git"
31
+ elsif /^[a-z]+:\/\/.*$/.match(repo_name) then
32
+ repo_name
33
+ else
34
+ raise "repo_name is written in invalid format: #{repo_name.inspect}"
35
+ end
36
+ end
37
+
38
+ def flavor(repo_name, *args)
39
+ options = Hash === args.last ? args.pop : {}
40
+ options[:groups] ||= []
41
+ version_contraint = VersionConstraint.new(args.last || '>= 0')
42
+
43
+ f = Flavor.new()
44
+ f.repo_name = repo_name
45
+ f.repo_uri = repo_uri_from_repo_name(repo_name)
46
+ f.version_contraint = version_contraint
47
+ f.groups = @default_groups + options[:groups]
48
+
49
+ @flavors[f.repo_uri] = f
50
+ end
51
+
52
+ def group(*group_names, &block)
53
+ @default_groups.concat(group_names)
54
+ yield
55
+ ensure
56
+ group_names.each do
57
+ @default_groups.pop()
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,64 @@
1
+ require 'yaml'
2
+
3
+ module Vim
4
+ module Flavor
5
+ class LockFile
6
+ # TODO: Resolve dependencies recursively.
7
+
8
+ attr_reader :flavors, :path
9
+
10
+ def initialize(path)
11
+ @flavors = {} # repo_uri => flavor
12
+ @path = path
13
+ end
14
+
15
+ def load()
16
+ h = File.open(@path, 'rb') do |f|
17
+ YAML.load(f.read())
18
+ end
19
+
20
+ @flavors = self.class.flavors_from_poro(h[:flavors])
21
+ end
22
+
23
+ def save()
24
+ h = {}
25
+
26
+ h[:flavors] = self.class.poro_from_flavors(@flavors)
27
+
28
+ File.open(@path, 'wb') do |f|
29
+ YAML.dump(h, f)
30
+ end
31
+ end
32
+
33
+ def self.poro_from_flavors(flavors)
34
+ Hash[
35
+ flavors.values.map {|f|
36
+ [
37
+ f.repo_uri,
38
+ {
39
+ :groups => f.groups,
40
+ :locked_version => f.locked_version.to_s(),
41
+ :repo_name => f.repo_name,
42
+ :version_contraint => f.version_contraint.to_s(),
43
+ }
44
+ ]
45
+ }
46
+ ]
47
+ end
48
+
49
+ def self.flavors_from_poro(poro)
50
+ Hash[
51
+ poro.to_a().map {|repo_uri, h|
52
+ f = Flavor.new()
53
+ f.groups = h[:groups]
54
+ f.locked_version = Gem::Version.create(h[:locked_version])
55
+ f.repo_name = h[:repo_name]
56
+ f.repo_uri = repo_uri
57
+ f.version_contraint = VersionConstraint.new(h[:version_contraint])
58
+ [f.repo_uri, f]
59
+ }
60
+ ]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,9 @@
1
+ module Vim
2
+ module Flavor
3
+ module StringExtension
4
+ def to_flavors_path()
5
+ "#{self}/flavors"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  module Vim
2
2
  module Flavor
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.3'
4
4
  end
5
5
  end
@@ -0,0 +1,48 @@
1
+ module Vim
2
+ module Flavor
3
+ class VersionConstraint
4
+ attr_reader :base_version, :operator
5
+
6
+ def initialize(s)
7
+ @base_version, @operator = parse(s)
8
+ end
9
+
10
+ def to_s()
11
+ "#{@operator} #{@base_version}"
12
+ end
13
+
14
+ def ==(other)
15
+ self.base_version == other.base_version &&
16
+ self.operator == other.operator
17
+ end
18
+
19
+ def parse(s)
20
+ m = /^\s*(>=|~>)\s+(\S+)$/.match(s)
21
+ if m then
22
+ [Gem::Version.create(m[2]), m[1]]
23
+ else
24
+ raise "Invalid version constraint: #{s.inspect}"
25
+ end
26
+ end
27
+
28
+ def compatible?(other_version_or_s)
29
+ v = Gem::Version.create(other_version_or_s)
30
+ if @operator == '~>' then
31
+ self.base_version.bump() > v and v >= self.base_version
32
+ elsif @operator == '>=' then
33
+ v >= self.base_version
34
+ else
35
+ raise NotImplementedError
36
+ end
37
+ end
38
+
39
+ def find_the_best_version(versions)
40
+ versions.
41
+ select {|v| compatible?(v)}.
42
+ sort().
43
+ reverse().
44
+ first
45
+ end
46
+ end
47
+ end
48
+ end
data/spec/facade_spec.rb CHANGED
@@ -250,7 +250,7 @@ describe Vim::Flavor::Facade do
250
250
  @flavor = Vim::Flavor::Flavor.new()
251
251
  @flavor.repo_name = '@test_repo_path'
252
252
  @flavor.repo_uri = @test_repo_path
253
- @flavor.locked_version = '1.0.0'
253
+ @flavor.locked_version = Gem::Version.create('1.0.0')
254
254
 
255
255
  @flavors = [@flavor]
256
256
 
data/spec/flavor_spec.rb CHANGED
@@ -28,7 +28,7 @@ describe Vim::Flavor::Flavor do
28
28
  @flavor = described_class.new()
29
29
  @flavor.repo_name = '@test_repo_path'
30
30
  @flavor.repo_uri = @test_repo_path
31
- @flavor.locked_version = '1.0.0'
31
+ @flavor.locked_version = Gem::Version.create('1.0.0')
32
32
  end
33
33
 
34
34
  it 'should clone the repository into a given path' do
@@ -51,7 +51,7 @@ describe Vim::Flavor::Flavor do
51
51
  @flavor = described_class.new()
52
52
  @flavor.repo_name = '@test_repo_path'
53
53
  @flavor.repo_uri = @test_repo_path
54
- @flavor.locked_version = '1.0.0'
54
+ @flavor.locked_version = Gem::Version.create('1.0.0')
55
55
  end
56
56
 
57
57
  it 'should fail if the repository is not cloned yet' do
@@ -91,7 +91,7 @@ describe Vim::Flavor::Flavor do
91
91
  @flavor = described_class.new()
92
92
  @flavor.repo_name = '@test_repo_path'
93
93
  @flavor.repo_uri = @test_repo_path
94
- @flavor.locked_version = '1.0.0'
94
+ @flavor.locked_version = Gem::Version.create('1.0.0')
95
95
 
96
96
  @vimfiles_path = "#{@tmp_path}/vimfiles"
97
97
  @deploy_path = @flavor.make_deploy_path(@vimfiles_path)
@@ -117,7 +117,7 @@ describe Vim::Flavor::Flavor do
117
117
  $?.should == 0
118
118
  tag_id = %x{
119
119
  cd #{@flavor.cached_repo_path.inspect} &&
120
- git rev-list -n1 #{@flavor.locked_version.inspect}
120
+ git rev-list -n1 '#{@flavor.locked_version}'
121
121
  }
122
122
  $?.should == 0
123
123
  head_id.should == tag_id
@@ -181,7 +181,7 @@ describe Vim::Flavor::Flavor do
181
181
  @flavor = described_class.new()
182
182
  @flavor.repo_name = '@test_repo_path'
183
183
  @flavor.repo_uri = @test_repo_path
184
- @flavor.locked_version = '1.0.0'
184
+ @flavor.locked_version = Gem::Version.create('1.0.0')
185
185
 
186
186
  @vimfiles_path = "#{@tmp_path}/vimfiles"
187
187
  @deploy_path = @flavor.make_deploy_path(@vimfiles_path)
@@ -209,7 +209,7 @@ describe Vim::Flavor::Flavor do
209
209
  @flavor = described_class.new()
210
210
  @flavor.repo_name = '@test_repo_path'
211
211
  @flavor.repo_uri = @test_repo_path
212
- @flavor.locked_version = '1.0.0'
212
+ @flavor.locked_version = Gem::Version.create('1.0.0')
213
213
  end
214
214
 
215
215
  it 'should list tags as versions' do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: vim-flavor
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Kana Natsuno
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-27 00:00:00 +09:00
13
+ date: 2012-04-06 00:00:00 +09:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -53,7 +53,14 @@ files:
53
53
  - Rakefile
54
54
  - bin/vim-flavor
55
55
  - lib/vim-flavor.rb
56
+ - lib/vim-flavor/cli.rb
57
+ - lib/vim-flavor/facade.rb
58
+ - lib/vim-flavor/flavor.rb
59
+ - lib/vim-flavor/flavorfile.rb
60
+ - lib/vim-flavor/lockfile.rb
61
+ - lib/vim-flavor/stringextension.rb
56
62
  - lib/vim-flavor/version.rb
63
+ - lib/vim-flavor/versionconstraint.rb
57
64
  - spec/cli_spec.rb
58
65
  - spec/facade_spec.rb
59
66
  - spec/flavor_spec.rb