vim-flavor 0.0.2 → 0.0.3

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.
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