tms 1.1.2 → 1.2.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.
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/bin/tms +34 -23
- data/lib/tms.rb +79 -67
- data/lib/tms/backup.rb +10 -8
- data/lib/tms/pathname.rb +49 -0
- data/lib/tms/space.rb +2 -0
- data/lib/tms/table.rb +39 -0
- data/tms.gemspec +4 -5
- metadata +12 -24
data/Rakefile
CHANGED
@@ -15,7 +15,6 @@ Jeweler::Tasks.new do |gem|
|
|
15
15
|
gem.authors = ['Boba Fat']
|
16
16
|
gem.add_runtime_dependency 'colored'
|
17
17
|
gem.add_runtime_dependency 'xattr'
|
18
|
-
gem.add_runtime_dependency 'mutter'
|
19
18
|
gem.add_development_dependency 'jeweler', '~> 1.5.1'
|
20
19
|
gem.add_development_dependency 'rake-compiler'
|
21
20
|
gem.add_development_dependency 'rake-gem-ghost'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/bin/tms
CHANGED
@@ -9,34 +9,45 @@ end
|
|
9
9
|
|
10
10
|
require 'optparse'
|
11
11
|
|
12
|
-
|
13
|
-
OptionParser.new do |op|
|
14
|
-
|
15
|
-
Usege:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
op.on('-d', '--directory DIRECTORY', 'Use backup directory') do |dir|
|
22
|
-
Tms::Backup.backups_dir = dir
|
23
|
-
end
|
12
|
+
def option_parser
|
13
|
+
OptionParser.new do |op|
|
14
|
+
op.banner = <<-BANNER
|
15
|
+
Usege:
|
16
|
+
List: #{op.program_name} [options]
|
17
|
+
Diff: #{op.program_name} [options] id|nxxx id|nxxx
|
18
|
+
Diff with previous: #{op.program_name} [options] id|nxxx
|
19
|
+
BANNER
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
op.on('-d', '--directory DIRECTORY', 'Use backup directory') do |dir|
|
22
|
+
Tms::Backup.backups_dir = dir
|
23
|
+
end
|
24
|
+
|
25
|
+
op.on('-f', '--filter DIRECTORY', 'Show diff starting from directory') do |dir|
|
26
|
+
Tms::Backup.filter_dir = dir
|
27
|
+
end
|
28
|
+
|
29
|
+
op.on('-p', '--[no-]progress', 'Show backups in progress') do |show_in_progress|
|
30
|
+
Tms::Backup.show_in_progress = show_in_progress
|
31
|
+
end
|
28
32
|
|
29
|
-
|
30
|
-
|
33
|
+
op.on('-l', '--[no-]long', 'Show more info about backup in list') do |show_all_columns|
|
34
|
+
Tms::Backup.show_all_columns = show_all_columns
|
35
|
+
end
|
31
36
|
end
|
32
|
-
end
|
37
|
+
end
|
38
|
+
|
39
|
+
options, ids = ARGV.partition{ |arg| arg =~ /^--?\D/ }
|
40
|
+
begin
|
41
|
+
option_parser.parse!(options)
|
42
|
+
rescue OptionParser::InvalidOption => e
|
43
|
+
abort e
|
44
|
+
end
|
33
45
|
|
34
|
-
ids = ids.map(&:to_i)
|
35
46
|
case ids.length
|
36
47
|
when 0
|
37
48
|
Tms.list
|
38
|
-
when 1
|
39
|
-
Tms.diff(ids
|
40
|
-
|
41
|
-
|
49
|
+
when 1..2
|
50
|
+
Tms.diff(*ids)
|
51
|
+
else
|
52
|
+
abort 'Max two arguments'
|
42
53
|
end
|
data/lib/tms.rb
CHANGED
@@ -1,80 +1,90 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
''
|
19
|
-
end
|
1
|
+
module Tms
|
2
|
+
class << self
|
3
|
+
def list
|
4
|
+
backups = Backup.list
|
5
|
+
Table.new do |t|
|
6
|
+
t.col '', :red
|
7
|
+
t.col '', :blue
|
8
|
+
t.col 'num'
|
9
|
+
t.col 'name'
|
10
|
+
if Backup.show_all_columns
|
11
|
+
t.col 'state'
|
12
|
+
t.col 'type'
|
13
|
+
t.col 'version'
|
14
|
+
t.col 'completed in', nil, :right
|
15
|
+
t.col 'started at'
|
16
|
+
t.col 'finished at'
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
19
|
+
backups.each_with_index do |b, i|
|
20
|
+
values = [
|
21
|
+
i,
|
22
|
+
i - backups.length,
|
23
|
+
b.number,
|
24
|
+
b.name
|
25
|
+
]
|
26
|
+
if Backup.show_all_columns
|
27
|
+
values += [
|
28
|
+
b.state,
|
29
|
+
b.type,
|
30
|
+
b.version,
|
31
|
+
format(b.completed_in, :time),
|
32
|
+
format(b.started_at, :date),
|
33
|
+
format(b.finished_at, :date)
|
34
|
+
]
|
35
35
|
end
|
36
|
-
|
37
|
-
size
|
36
|
+
t << values
|
38
37
|
end
|
38
|
+
end.print
|
39
|
+
end
|
40
|
+
|
41
|
+
def diff(a, b = nil)
|
42
|
+
a_id = backup_id(a)
|
43
|
+
if b
|
44
|
+
b_id = backup_id(b)
|
39
45
|
else
|
40
|
-
|
46
|
+
if Backup.list.length == 1
|
47
|
+
abort("Only one backup exist")
|
48
|
+
elsif a_id == 0 || (Backup.list[a_id] && !Backup.list[a_id - 1])
|
49
|
+
abort("No backup before oldest one")
|
50
|
+
else
|
51
|
+
a_id, b_id = a_id - 1, a_id
|
52
|
+
end
|
41
53
|
end
|
54
|
+
backup_a = Backup.list[a_id] or abort("No backup #{a}")
|
55
|
+
backup_b = Backup.list[b_id] or abort("No backup #{b}")
|
56
|
+
Backup.diff(backup_a, backup_b)
|
42
57
|
end
|
43
|
-
end
|
44
58
|
|
45
|
-
|
46
|
-
case size = count_size(options)
|
47
|
-
when nil
|
48
|
-
'!!!!!!'
|
49
|
-
when 0
|
50
|
-
' '
|
51
|
-
else
|
52
|
-
Tms::Space.space(size, :color => true)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
59
|
+
private
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
column :align => :right
|
65
|
-
column
|
66
|
-
end.tap do |table|
|
67
|
-
table << ['', '', 'num', 'name']
|
68
|
-
backups.each_with_index do |backup, i|
|
69
|
-
table << [i, i - backups.length, backup.number, backup.name]
|
70
|
-
end
|
71
|
-
end.print
|
61
|
+
def backup_id(arg)
|
62
|
+
if arg[0, 1] == 'n'
|
63
|
+
number = arg[/\d+/].to_i
|
64
|
+
Backup.list.index{ |backup| backup.number == number }
|
65
|
+
else
|
66
|
+
arg.to_i
|
67
|
+
end
|
72
68
|
end
|
73
69
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
70
|
+
def format(value, type)
|
71
|
+
case type
|
72
|
+
when :time
|
73
|
+
case value
|
74
|
+
when 0...60
|
75
|
+
"#{value.round} sec"
|
76
|
+
when 60...3600
|
77
|
+
'%.1f min' % (value / 60)
|
78
|
+
when 3600...86400
|
79
|
+
'%.1f hou' % (value / 3600)
|
80
|
+
else
|
81
|
+
'%.1f day' % (value / 86400)
|
82
|
+
end
|
83
|
+
when :date
|
84
|
+
value.strftime('%Y-%m-%d %H:%M:%S')
|
85
|
+
else
|
86
|
+
value
|
87
|
+
end
|
78
88
|
end
|
79
89
|
end
|
80
90
|
end
|
@@ -82,3 +92,5 @@ end
|
|
82
92
|
require 'tms.so'
|
83
93
|
require 'tms/backup'
|
84
94
|
require 'tms/space'
|
95
|
+
require 'tms/table'
|
96
|
+
require 'tms/pathname'
|
data/lib/tms/backup.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'colored'
|
2
|
+
require 'xattr'
|
3
|
+
|
1
4
|
class Tms::Backup
|
2
5
|
class << self
|
3
6
|
def backups_dir
|
@@ -9,7 +12,7 @@ class Tms::Backup
|
|
9
12
|
abort 'can\'t get computer name' unless $?.success?
|
10
13
|
|
11
14
|
backups_dir = Pathname(backup_volume) + 'Backups.backupdb' + computer_name
|
12
|
-
abort "ops backups dir is not a dir" unless backups_dir.directory?
|
15
|
+
abort "ops! backups dir is not a dir" unless backups_dir.directory?
|
13
16
|
|
14
17
|
backups_dir
|
15
18
|
end
|
@@ -20,23 +23,22 @@ class Tms::Backup
|
|
20
23
|
|
21
24
|
attr_accessor :filter_dir
|
22
25
|
attr_accessor :show_in_progress
|
26
|
+
attr_accessor :show_all_columns
|
23
27
|
|
24
28
|
def list
|
25
29
|
@list ||= begin
|
26
|
-
|
27
|
-
backups_dir.children.each do |path|
|
30
|
+
backups_dir.children.map do |path|
|
28
31
|
case path.basename.to_s
|
29
32
|
when /^\d{4}-\d{2}-\d{2}-\d{6}$/
|
30
|
-
|
33
|
+
new(path)
|
31
34
|
when /^\d{4}-\d{2}-\d{2}-\d{6}\.inProgress$/
|
32
35
|
if show_in_progress
|
33
36
|
path.children.select(&:directory?).each do |path_in_progress|
|
34
|
-
|
37
|
+
new(path_in_progress, true)
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
38
|
-
end
|
39
|
-
backups.sort
|
41
|
+
end.flatten.compact.sort
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
@@ -65,7 +67,7 @@ class Tms::Backup
|
|
65
67
|
puts "#{'█ '.blue} #{a.colored_size(:recursive => true)} #{path}#{a.postfix}"
|
66
68
|
0
|
67
69
|
when a.ftype != b.ftype
|
68
|
-
puts "#{'!!!'.red.bold} #{a.colored_size} #{path} (#{a.ftype}=>#{b.ftype})"
|
70
|
+
puts "#{'!!!'.red.bold} #{a.colored_size(:recursive => true)} #{path} (#{a.ftype}=>#{b.ftype})"
|
69
71
|
b.count_size || 0
|
70
72
|
when a.lino != b.lino
|
71
73
|
if a.readable? && b.readable?
|
data/lib/tms/pathname.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
class Pathname
|
4
|
+
def real_directory?
|
5
|
+
directory? && !symlink?
|
6
|
+
end
|
7
|
+
|
8
|
+
def lino
|
9
|
+
@ino ||= lstat.ino
|
10
|
+
end
|
11
|
+
|
12
|
+
def postfix
|
13
|
+
case
|
14
|
+
when symlink?
|
15
|
+
'@'
|
16
|
+
when directory?
|
17
|
+
'/'
|
18
|
+
else
|
19
|
+
''
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def count_size(options = {})
|
24
|
+
if @count_size.nil?
|
25
|
+
if exist?
|
26
|
+
if directory?
|
27
|
+
@counted_size = 0
|
28
|
+
find{ |path| @counted_size += path.size rescue nil } if options[:recursive]
|
29
|
+
else
|
30
|
+
@counted_size = size
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@counted_size = false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@counted_size
|
37
|
+
end
|
38
|
+
|
39
|
+
def colored_size(options = {})
|
40
|
+
case size = count_size(options)
|
41
|
+
when false
|
42
|
+
'!!!!!!'
|
43
|
+
when 0
|
44
|
+
' '
|
45
|
+
else
|
46
|
+
Tms::Space.space(size, :color => true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/tms/space.rb
CHANGED
data/lib/tms/table.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'colored'
|
2
|
+
|
3
|
+
class Tms::Table
|
4
|
+
attr_accessor :cols, :rows
|
5
|
+
|
6
|
+
def initialize(&block)
|
7
|
+
@cols, @rows = [], []
|
8
|
+
yield self if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
ADJUST = {:left => :ljust, :right => :rjust, :center => :center}
|
12
|
+
def col(name, color = nil, adjust = nil)
|
13
|
+
@cols << {:name => name, :color => color, :adjust => ADJUST[adjust]}
|
14
|
+
end
|
15
|
+
|
16
|
+
def <<(row)
|
17
|
+
@rows << row
|
18
|
+
end
|
19
|
+
|
20
|
+
def lines
|
21
|
+
@cols.each_with_index do |col, i|
|
22
|
+
col[:width] = ([col[:name]] + @rows.map{ |row| row[i] }).map(&:to_s).map(&:length).max
|
23
|
+
end
|
24
|
+
|
25
|
+
([@cols.map{ |col| col[:name] }] + @rows).each_with_index.map do |line, i|
|
26
|
+
line.zip(@cols).map do |val, col|
|
27
|
+
width, color, adjust = col.values_at(:width, :color, :adjust)
|
28
|
+
adjust ||= val.is_a?(Integer) ? :rjust : :ljust
|
29
|
+
val_s = val.to_s.send(adjust, width)
|
30
|
+
val_s = Colored.colorize(val_s, :foreground => color) if color
|
31
|
+
val_s
|
32
|
+
end.join(' ')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def print
|
37
|
+
puts lines
|
38
|
+
end
|
39
|
+
end
|
data/tms.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tms}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Boba Fat"]
|
12
|
-
s.date = %q{2010-12-
|
12
|
+
s.date = %q{2010-12-06}
|
13
13
|
s.default_executable = %q{tms}
|
14
14
|
s.description = %q{View avaliable Time Machine backups and show diff}
|
15
15
|
s.executables = ["tms"]
|
@@ -28,7 +28,9 @@ Gem::Specification.new do |s|
|
|
28
28
|
"ext/tms/tms.c",
|
29
29
|
"lib/tms.rb",
|
30
30
|
"lib/tms/backup.rb",
|
31
|
+
"lib/tms/pathname.rb",
|
31
32
|
"lib/tms/space.rb",
|
33
|
+
"lib/tms/table.rb",
|
32
34
|
"tms.gemspec"
|
33
35
|
]
|
34
36
|
s.homepage = %q{http://github.com/toy/tms}
|
@@ -44,14 +46,12 @@ Gem::Specification.new do |s|
|
|
44
46
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
47
|
s.add_runtime_dependency(%q<colored>, [">= 0"])
|
46
48
|
s.add_runtime_dependency(%q<xattr>, [">= 0"])
|
47
|
-
s.add_runtime_dependency(%q<mutter>, [">= 0"])
|
48
49
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
49
50
|
s.add_development_dependency(%q<rake-compiler>, [">= 0"])
|
50
51
|
s.add_development_dependency(%q<rake-gem-ghost>, [">= 0"])
|
51
52
|
else
|
52
53
|
s.add_dependency(%q<colored>, [">= 0"])
|
53
54
|
s.add_dependency(%q<xattr>, [">= 0"])
|
54
|
-
s.add_dependency(%q<mutter>, [">= 0"])
|
55
55
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
56
56
|
s.add_dependency(%q<rake-compiler>, [">= 0"])
|
57
57
|
s.add_dependency(%q<rake-gem-ghost>, [">= 0"])
|
@@ -59,7 +59,6 @@ Gem::Specification.new do |s|
|
|
59
59
|
else
|
60
60
|
s.add_dependency(%q<colored>, [">= 0"])
|
61
61
|
s.add_dependency(%q<xattr>, [">= 0"])
|
62
|
-
s.add_dependency(%q<mutter>, [">= 0"])
|
63
62
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
64
63
|
s.add_dependency(%q<rake-compiler>, [">= 0"])
|
65
64
|
s.add_dependency(%q<rake-gem-ghost>, [">= 0"])
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
- 1
|
9
8
|
- 2
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Boba Fat
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-12-
|
18
|
+
date: 2010-12-06 00:00:00 +03:00
|
19
19
|
default_executable: tms
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -46,24 +46,10 @@ dependencies:
|
|
46
46
|
version: "0"
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: mutter
|
51
|
-
prerelease: false
|
52
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
-
none: false
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
hash: 3
|
58
|
-
segments:
|
59
|
-
- 0
|
60
|
-
version: "0"
|
61
|
-
type: :runtime
|
62
|
-
version_requirements: *id003
|
63
49
|
- !ruby/object:Gem::Dependency
|
64
50
|
name: jeweler
|
65
51
|
prerelease: false
|
66
|
-
requirement: &
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
67
53
|
none: false
|
68
54
|
requirements:
|
69
55
|
- - ~>
|
@@ -75,11 +61,11 @@ dependencies:
|
|
75
61
|
- 1
|
76
62
|
version: 1.5.1
|
77
63
|
type: :development
|
78
|
-
version_requirements: *
|
64
|
+
version_requirements: *id003
|
79
65
|
- !ruby/object:Gem::Dependency
|
80
66
|
name: rake-compiler
|
81
67
|
prerelease: false
|
82
|
-
requirement: &
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
83
69
|
none: false
|
84
70
|
requirements:
|
85
71
|
- - ">="
|
@@ -89,11 +75,11 @@ dependencies:
|
|
89
75
|
- 0
|
90
76
|
version: "0"
|
91
77
|
type: :development
|
92
|
-
version_requirements: *
|
78
|
+
version_requirements: *id004
|
93
79
|
- !ruby/object:Gem::Dependency
|
94
80
|
name: rake-gem-ghost
|
95
81
|
prerelease: false
|
96
|
-
requirement: &
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
97
83
|
none: false
|
98
84
|
requirements:
|
99
85
|
- - ">="
|
@@ -103,7 +89,7 @@ dependencies:
|
|
103
89
|
- 0
|
104
90
|
version: "0"
|
105
91
|
type: :development
|
106
|
-
version_requirements: *
|
92
|
+
version_requirements: *id005
|
107
93
|
description: View avaliable Time Machine backups and show diff
|
108
94
|
email:
|
109
95
|
executables:
|
@@ -123,7 +109,9 @@ files:
|
|
123
109
|
- ext/tms/tms.c
|
124
110
|
- lib/tms.rb
|
125
111
|
- lib/tms/backup.rb
|
112
|
+
- lib/tms/pathname.rb
|
126
113
|
- lib/tms/space.rb
|
114
|
+
- lib/tms/table.rb
|
127
115
|
- tms.gemspec
|
128
116
|
has_rdoc: true
|
129
117
|
homepage: http://github.com/toy/tms
|