confgit 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/confgit/repo.rb +48 -16
  3. data/spec/confgit_spec.rb +78 -11
  4. metadata +3 -3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/confgit/repo.rb CHANGED
@@ -247,9 +247,16 @@ class Repo
247
247
  # ファイルの hash値を求める
248
248
  def hash_object(file)
249
249
  path = File.expand_path(file)
250
- open("| git hash-object \"#{path}\"") {|f|
251
- return f.gets.chomp
252
- }
250
+
251
+ if File.symlink?(path)
252
+ mode = '120000'
253
+ hash = `readlink "#{path}" | git hash-object --stdin`.chomp
254
+ else
255
+ mode = File.executable?(path) ? '100755' : '100644'
256
+ hash = `git hash-object "#{path}"`.chomp
257
+ end
258
+
259
+ "#{mode} #{hash}"
253
260
  end
254
261
 
255
262
  # 確認プロンプトを表示する
@@ -270,21 +277,42 @@ class Repo
270
277
  y
271
278
  end
272
279
 
280
+ # ファイルが存在するか?(シンボリックリンクの場合も対象にする)
281
+ def file_exist?(path)
282
+ File.exist?(path) || File.symlink?(path)
283
+ end
284
+
285
+ # ファイルがディレクトリか?(シンボリックリンクの場合は対象外)
286
+ def file_directory?(path)
287
+ File.directory?(path) && ! File.symlink?(path)
288
+ end
289
+
290
+ # ファイルが書込み可能か?(シンボリックリンクの場合はわからないのでとりあえず true を返す)
291
+ def file_writable_real?(path)
292
+ return true if File.symlink?(path)
293
+ return File.writable_real?(File.dirname(path)) unless File.exist?(path)
294
+
295
+ File.writable_real?(path)
296
+ end
297
+
273
298
  # ファイルのコピー(属性は維持する)
274
299
  def filecopy(from, to, exiting = false)
275
300
  begin
276
301
  to_dir = File.dirname(to)
277
302
  FileUtils.mkpath(to_dir)
278
303
 
279
- if File.exist?(to) && ! File.writable_real?(to)
304
+ if File.symlink?(to)
305
+ # シンボリックリンクの場合は削除する
306
+ File.unlink(to)
307
+ elsif File.exist?(to) && ! File.writable_real?(to)
280
308
  # 書込みできない場合は削除を試みる
281
309
  File.unlink(to)
282
310
  end
283
311
 
284
312
  FileUtils.copy_entry(from, to)
285
- stat = File.stat(from)
286
313
 
287
- unless File.symlink?(to)
314
+ unless File.symlink?(from) || File.symlink?(to)
315
+ stat = File.stat(from)
288
316
  File.utime(stat.atime, stat.mtime, to)
289
317
  File.chmod(stat.mode, to)
290
318
  end
@@ -327,7 +355,7 @@ class Repo
327
355
 
328
356
  # file = line.chomp
329
357
  next if /^\.git/ =~ file
330
- next if File.directory?(file)
358
+ next if file_directory?(file)
331
359
 
332
360
  yield(file, hash)
333
361
  end
@@ -386,7 +414,7 @@ class Repo
386
414
 
387
415
  # ファイルの更新チェック
388
416
  def modfile?(from, to)
389
- ! File.exist?(to) || hash_object(from) != hash_object(to)
417
+ ! file_exist?(to) || hash_object(from) != hash_object(to)
390
418
  end
391
419
 
392
420
  # ファイル属性を文字列にする
@@ -481,7 +509,7 @@ class Repo
481
509
  next
482
510
  end
483
511
 
484
- if File.directory?(path) && ! File.symlink?(path)
512
+ if file_directory?(path)
485
513
  dir_each(path) { |file|
486
514
  next if File.directory?(file)
487
515
 
@@ -522,12 +550,12 @@ class Repo
522
550
  # バックアップする
523
551
  def confgit_backup(options, *args)
524
552
  git_each(*args) { |file, hash|
525
- next if File.directory?(file)
553
+ next if file_directory?(file)
526
554
 
527
555
  from = File.join(root, file)
528
556
  to = File.join(@repo_path, file)
529
557
 
530
- unless File.exist?(from)
558
+ unless file_exist?(from)
531
559
  with_color(:fg_red) { print "[?] #{file}" }
532
560
  puts
533
561
  next
@@ -554,19 +582,19 @@ class Repo
554
582
  # リストアする
555
583
  def confgit_restore(options, *args)
556
584
  git_each(*args) { |file, hash|
557
- next if File.directory?(file)
585
+ next if file_directory?(file)
558
586
 
559
587
  from = File.join(@repo_path, file)
560
588
  to = File.join(root, file)
561
589
 
562
- unless File.exist?(from)
590
+ unless file_exist?(from)
563
591
  with_color(:fg_red) { print "[?] #{file}" }
564
592
  puts
565
593
  next
566
594
  end
567
595
 
568
596
  if options[:force] || modfile?(from, to)
569
- color = File.writable_real?(to) ? :fg_blue : :fg_magenta
597
+ color = file_writable_real?(to) ? :fg_blue : :fg_magenta
570
598
  with_color(color) { print "<-- #{file}" }
571
599
  write = options[:yes]
572
600
 
@@ -585,12 +613,16 @@ class Repo
585
613
  # 一覧表示する
586
614
  def confgit_list(options, *args)
587
615
  git_each(*args) { |file, hash|
588
- next if File.directory?(file)
616
+ next if file_directory?(file)
589
617
 
590
618
  from = File.join(root, file)
591
619
  to = File.join(@repo_path, file)
592
620
 
593
- if File.exist?(from)
621
+ if File.symlink?(from)
622
+ mode = options[:octal] ? '120000' : 'l---------'
623
+ user = '-'
624
+ group = '-'
625
+ elsif File.exist?(from)
594
626
  stat = File.stat(from)
595
627
  mode = options[:octal] ? stat.mode.to_s(8) : mode2str(stat.mode)
596
628
  user = Etc.getpwuid(stat.uid).name
data/spec/confgit_spec.rb CHANGED
@@ -305,13 +305,28 @@ describe Confgit do
305
305
 
306
306
  describe "backup" do
307
307
  before do
308
+ dir = 'misc'
308
309
  @mod_file = 'VERSION'
309
310
  @data = '0.0.1'
311
+ @symlinks = {'dir_link' => dir, 'file_link' => 'VERSION', 'mod_link' => ['README', 'LICENSE.txt']}
310
312
 
311
- chroot(@mod_file, 'README', 'LICENSE.txt') { |root, *files|
312
- confgit 'add', *files
313
+ chroot(@mod_file, 'README', 'LICENSE.txt', File.join(dir, 'README')) { |root, *files|
314
+ @symlinks.each { |key, value|
315
+ file, = value
316
+ File.symlink(file, key)
317
+ }
318
+
319
+ confgit 'add', *(files + @symlinks.keys)
313
320
  capture_io { confgit 'commit', '-m', "add #{files}" }
314
321
  open(@mod_file, 'w') { |f| f.puts @data }
322
+
323
+ @symlinks.each { |key, value|
324
+ old, file = value
325
+ next unless file
326
+
327
+ File.delete(key)
328
+ File.symlink(file, key)
329
+ }
315
330
  }
316
331
  end
317
332
 
@@ -319,6 +334,7 @@ describe Confgit do
319
334
  chroot { |root, *files|
320
335
  proc { confgit 'backup', '-n' }.must_output <<-EOD.cut_indent
321
336
  \e[34m--> #{@mod_file}\e[m
337
+ \e[34m--> mod_link\e[m
322
338
  # On branch master
323
339
  nothing to commit (working directory clean)
324
340
  EOD
@@ -329,12 +345,14 @@ describe Confgit do
329
345
  chroot { |root, *files|
330
346
  proc { confgit 'backup', '-y' }.must_output <<-EOD.cut_indent
331
347
  \e[34m--> VERSION\e[m
348
+ \e[34m--> mod_link\e[m
332
349
  # On branch master
333
350
  # Changes not staged for commit:
334
351
  # (use "git add <file>..." to update what will be committed)
335
352
  # (use "git checkout -- <file>..." to discard changes in working directory)
336
353
  #
337
354
  # modified: #{@mod_file}
355
+ # modified: mod_link
338
356
  #
339
357
  no changes added to commit (use "git add" and/or "git commit -a")
340
358
  EOD
@@ -349,6 +367,10 @@ describe Confgit do
349
367
  \e[34m--> LICENSE.txt\e[m
350
368
  \e[34m--> README\e[m
351
369
  \e[31m[?] #{@mod_file}\e[m
370
+ \e[34m--> dir_link\e[m
371
+ \e[34m--> file_link\e[m
372
+ \e[34m--> misc/README\e[m
373
+ \e[34m--> mod_link\e[m
352
374
  # On branch master
353
375
  nothing to commit (working directory clean)
354
376
  EOD
@@ -357,23 +379,46 @@ describe Confgit do
357
379
  end
358
380
 
359
381
  describe "restore" do
382
+ def udpate_data
383
+ open(@mod_file, 'w') { |f| f.puts @data }
384
+ File.delete @del_file
385
+
386
+ @symlinks.each { |key, value|
387
+ old, file = value
388
+ next unless file
389
+
390
+ File.delete(key)
391
+ File.symlink(file, key)
392
+ }
393
+ end
394
+
360
395
  before do
396
+ dir = 'misc'
361
397
  @mod_file = 'VERSION'
398
+ @del_file = 'LICENSE.txt'
362
399
  @data = '0.0.1'
400
+ @symlinks = {'dir_link' => dir, 'file_link' => 'VERSION', 'mod_link' => ['README', 'LICENSE.txt']}
363
401
 
364
- chroot(@mod_file, 'README', 'LICENSE.txt') { |root, *files|
365
- confgit 'add', *files
402
+ chroot(@mod_file, @del_file, 'README', File.join(dir, 'README')) { |root, *files|
403
+ @symlinks.each { |key, value|
404
+ file, = value
405
+ File.symlink(file, key)
406
+ }
407
+
408
+ confgit 'add', *(files + @symlinks.keys)
366
409
  capture_io { confgit 'commit', '-m', "add #{files}" }
367
410
  }
368
411
  end
369
412
 
370
413
  it "restore -n" do
371
414
  chroot { |root, *files|
372
- open(@mod_file, 'w') { |f| f.puts @data }
415
+ udpate_data
373
416
 
374
417
  modfile(@mod_file) { |prev|
375
418
  proc { confgit 'restore', '-n' }.must_output <<-EOD.cut_indent
419
+ \e[34m<-- #{@del_file}\e[m
376
420
  \e[34m<-- #{@mod_file}\e[m
421
+ \e[34m<-- mod_link\e[m
377
422
  EOD
378
423
  open(@mod_file).read.must_equal prev
379
424
  }
@@ -383,10 +428,12 @@ describe Confgit do
383
428
  it "restore -y" do
384
429
  chroot { |root, *files|
385
430
  modfile(@mod_file) { |prev|
386
- open(@mod_file, 'w') { |f| f.puts @data }
431
+ udpate_data
387
432
 
388
433
  proc { confgit 'restore', '-y' }.must_output <<-EOD.cut_indent
434
+ \e[34m<-- #{@del_file}\e[m
389
435
  \e[34m<-- #{@mod_file}\e[m
436
+ \e[34m<-- mod_link\e[m
390
437
  EOD
391
438
  open(@mod_file).read.must_equal prev
392
439
  }
@@ -395,12 +442,16 @@ describe Confgit do
395
442
 
396
443
  it "restore -fn" do
397
444
  chroot { |root, *files|
398
- File.delete @mod_file
445
+ udpate_data
399
446
 
400
447
  proc { confgit 'restore', '-fn' }.must_output <<-EOD.cut_indent
401
- \e[34m<-- LICENSE.txt\e[m
448
+ \e[34m<-- #{@del_file}\e[m
402
449
  \e[34m<-- README\e[m
403
- \e[35m<-- #{@mod_file}\e[m
450
+ \e[34m<-- #{@mod_file}\e[m
451
+ \e[34m<-- dir_link\e[m
452
+ \e[34m<-- file_link\e[m
453
+ \e[34m<-- misc/README\e[m
454
+ \e[34m<-- mod_link\e[m
404
455
  EOD
405
456
  }
406
457
  end
@@ -424,8 +475,16 @@ describe Confgit do
424
475
 
425
476
  describe "list" do
426
477
  before do
427
- chroot('VERSION', 'README', 'LICENSE.txt') { |root, *files|
428
- confgit 'add', *files
478
+ dir = 'misc'
479
+ symlinks = {'dir_link' => dir, 'file_link' => 'VERSION', 'mod_link' => ['README', 'LICENSE.txt']}
480
+
481
+ chroot('VERSION', 'README', 'LICENSE.txt', File.join(dir, 'README')) { |root, *files|
482
+ symlinks.each { |key, value|
483
+ file, = value
484
+ File.symlink(file, key)
485
+ }
486
+
487
+ confgit 'add', *(files + symlinks.keys)
429
488
  capture_io { confgit 'commit', '-m', "add #{files}" }
430
489
  }
431
490
  end
@@ -437,6 +496,10 @@ describe Confgit do
437
496
  -rw-r--r-- .+ .+ #{root}/LICENSE\.txt
438
497
  -rw-r--r-- .+ .+ #{root}/README
439
498
  -rw-r--r-- .+ .+ #{root}/VERSION
499
+ l--------- .+ .+ #{root}/dir_link
500
+ l--------- .+ .+ #{root}/file_link
501
+ -rw-r--r-- .+ .+ #{root}/misc/README
502
+ l--------- .+ .+ #{root}/mod_link
440
503
  EOD
441
504
  }
442
505
  end
@@ -448,6 +511,10 @@ describe Confgit do
448
511
  100644 .+ .+ #{root}/LICENSE\.txt
449
512
  100644 .+ .+ #{root}/README
450
513
  100644 .+ .+ #{root}/VERSION
514
+ 120000 .+ .+ #{root}/dir_link
515
+ 120000 .+ .+ #{root}/file_link
516
+ 100644 .+ .+ #{root}/misc/README
517
+ 120000 .+ .+ #{root}/mod_link
451
518
  EOD
452
519
  }
453
520
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: confgit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-20 00:00:00.000000000 Z
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
@@ -106,7 +106,7 @@ homepage: https://github.com/gnue/confgit
106
106
  licenses: []
107
107
  post_install_message: ! "\n ==================\n This software requires 'git'.\n
108
108
  \ Also optional softwares 'tree' and 'tig'.\n\n If you are using the bash-completion\n\n
109
- \ $ cp `gem env gemdir`/gems/confgit-0.0.4/etc/bash_completion.d/confgit $BASH_COMPLETION_DIR\n\n
109
+ \ $ cp `gem env gemdir`/gems/confgit-0.0.5/etc/bash_completion.d/confgit $BASH_COMPLETION_DIR\n\n
110
110
  \ ==================\n "
111
111
  rdoc_options: []
112
112
  require_paths: