dutiful 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.
- checksums.yaml +4 -4
- data/bin/dutiful +2 -2
- data/config/dropbox.toml +3 -0
- data/config/icloud.toml +3 -0
- data/db/bundler.toml +5 -0
- data/db/dutiful.toml +5 -0
- data/db/fish.toml +5 -0
- data/db/git.toml +5 -0
- data/db/iterm2.toml +5 -0
- data/db/tmux.toml +5 -0
- data/db/vim.toml +8 -0
- data/lib/dutiful/application.rb +39 -54
- data/lib/dutiful/application_file.rb +46 -0
- data/lib/dutiful/commands/list.rb +7 -0
- data/lib/dutiful/commands/main.rb +21 -0
- data/lib/dutiful/commands/sync.rb +23 -0
- data/lib/dutiful/commands.rb +6 -0
- data/lib/dutiful/config.rb +2 -2
- data/lib/dutiful/storage.rb +27 -26
- data/lib/dutiful/version.rb +1 -1
- data/lib/dutiful.rb +8 -2
- metadata +45 -5
- data/lib/dutiful/command.rb +0 -52
- data/lib/dutiful/file.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8a2e348ad20c4d7f7f6c8020c335d26f307fcbb
|
4
|
+
data.tar.gz: 40ec00a948a65351aeaa8c0a79282f4e6f5bd2a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a83c9c088f34fa2e491f7a36398ee11336e0b9dc36a2d440aa251efe077f6a716c8d39902beb508016b87f81bf7054f7ebcfd8ba34253b2ecb5e4fe1f7bc6c11
|
7
|
+
data.tar.gz: 6496d9a4531a3eefe2099f4c91e8bc76efc3385e2fb46f44d25f571d4a9042888320488e751f68c6e0353148c1562eba0281a8764de5639ce50ed9b57aff8460
|
data/bin/dutiful
CHANGED
data/config/dropbox.toml
ADDED
data/config/icloud.toml
ADDED
data/db/bundler.toml
ADDED
data/db/dutiful.toml
ADDED
data/db/fish.toml
ADDED
data/db/git.toml
ADDED
data/db/iterm2.toml
ADDED
data/db/tmux.toml
ADDED
data/db/vim.toml
ADDED
data/lib/dutiful/application.rb
CHANGED
@@ -1,69 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class Dutiful::Application
|
2
|
+
def initialize(path)
|
3
|
+
@path = path
|
4
|
+
end
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
def name
|
7
|
+
content[:application][:name]
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def files
|
11
|
+
content[:files].map { |file| Dutiful::ApplicationFile.new file[:path] }
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def exist?
|
15
|
+
files.any? &:exist?
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
18
|
+
def sync
|
19
|
+
files.each do |file|
|
20
|
+
if file.exist? || file.has_backup?
|
21
|
+
result = Dutiful::Config.storage.sync(file)
|
22
|
+
yield file, result if block_given?
|
23
|
+
else
|
24
|
+
yield file if block_given?
|
27
25
|
end
|
28
26
|
end
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
files.each_with_index do |file, index|
|
34
|
-
next unless file.exist?
|
35
|
-
|
36
|
-
if file.synced?
|
37
|
-
output << " #{file.path} ✔".green
|
38
|
-
else
|
39
|
-
output << " #{file.path} (pending)".yellow
|
40
|
-
end
|
41
|
-
|
42
|
-
output << "\n" if index < files.count
|
43
|
-
end
|
29
|
+
def to_s
|
30
|
+
output = "#{name}:\n"
|
44
31
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Dir.foreach('db').map do |filename|
|
50
|
-
next if filename == '.' or filename == '..'
|
32
|
+
output << files.map do |file|
|
33
|
+
" #{file}" if file.exist? || file.has_backup?
|
34
|
+
end.compact.join("\n")
|
35
|
+
end
|
51
36
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
37
|
+
def self.all
|
38
|
+
Dir["#{Dutiful.dir}/db/*.toml"].map do |filename|
|
39
|
+
Dutiful::Application.new filename
|
40
|
+
end.compact
|
41
|
+
end
|
56
42
|
|
57
|
-
|
58
|
-
|
43
|
+
def self.each
|
44
|
+
return enum_for(:each) unless block_given?
|
59
45
|
|
60
|
-
|
61
|
-
|
46
|
+
all.each { |application| yield application }
|
47
|
+
end
|
62
48
|
|
63
|
-
|
49
|
+
private
|
64
50
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
51
|
+
def content
|
52
|
+
@content ||= Tomlrb.load_file(@path, symbolize_keys: true)
|
68
53
|
end
|
69
54
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class Dutiful::ApplicationFile
|
2
|
+
attr_reader :full_path, :path
|
3
|
+
|
4
|
+
def initialize(path)
|
5
|
+
@path = path
|
6
|
+
@full_path = File.expand_path "~/#{path}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def backup_path
|
10
|
+
Dutiful::Config.storage.path path
|
11
|
+
end
|
12
|
+
|
13
|
+
def backup_timestamp
|
14
|
+
File.mtime backup_path if has_backup?
|
15
|
+
end
|
16
|
+
|
17
|
+
def timestamp
|
18
|
+
File.mtime full_path if exist?
|
19
|
+
end
|
20
|
+
|
21
|
+
def exist?
|
22
|
+
File.exist? full_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_backup?
|
26
|
+
Dutiful::Config.storage.exist? self
|
27
|
+
end
|
28
|
+
|
29
|
+
def synced?
|
30
|
+
has_backup? && Dutiful::Config.storage.synced?(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
if exist?
|
35
|
+
return "#{path} ✔".green if synced?
|
36
|
+
|
37
|
+
if has_backup?
|
38
|
+
return "#{path} (modified)".yellow
|
39
|
+
else
|
40
|
+
return "#{path} (pending backup)".yellow
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
"#{path} (pending restore)".yellow if has_backup?
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Dutiful::Command::Main < Clamp::Command
|
2
|
+
option ['-v', '--version'], :flag, 'Show version' do
|
3
|
+
puts "dutiful #{Dutiful::VERSION}"
|
4
|
+
exit 0
|
5
|
+
end
|
6
|
+
|
7
|
+
subcommand 'sync', 'Sync all preference files', Dutiful::Command::Sync
|
8
|
+
subcommand 'list', 'List all preference files', Dutiful::Command::List
|
9
|
+
|
10
|
+
subcommand 'restore', 'Restore all preference files' do
|
11
|
+
def execute
|
12
|
+
puts 'Not implemented yet'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
subcommand 'which', 'Display the full path to a preference file' do
|
17
|
+
def execute
|
18
|
+
puts 'Not implemented yet'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Dutiful::Command::Sync < Clamp::Command
|
2
|
+
option ['-v', '--verbose'], :flag, 'Verbose mode'
|
3
|
+
|
4
|
+
def execute
|
5
|
+
puts "Storage: #{Dutiful::Config.storage.name}\n\n"
|
6
|
+
|
7
|
+
Dutiful::Application.each do |application|
|
8
|
+
puts "#{application.name}:\n"
|
9
|
+
|
10
|
+
application.sync do |file, result|
|
11
|
+
if result
|
12
|
+
if result.success?
|
13
|
+
puts " #{file.path} ✔".green
|
14
|
+
else
|
15
|
+
puts " #{file.path} ✖ - #{result.error}".red
|
16
|
+
end
|
17
|
+
else
|
18
|
+
puts " #{file.path} does not exist (skipping)".yellow if verbose?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/dutiful/config.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Dutiful::Config
|
2
|
-
PATH =
|
2
|
+
PATH = File.expand_path '~/.dutiful/config.toml'
|
3
3
|
|
4
4
|
def self.storage
|
5
5
|
@storage ||= if content[:storage]
|
@@ -15,6 +15,6 @@ class Dutiful::Config
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def self.content
|
18
|
-
@content ||= Tomlrb.load_file(PATH, symbolize_keys: true)
|
18
|
+
@content ||= Tomlrb.load_file(PATH, symbolize_keys: true) rescue {}
|
19
19
|
end
|
20
20
|
end
|
data/lib/dutiful/storage.rb
CHANGED
@@ -2,59 +2,60 @@ require 'fileutils'
|
|
2
2
|
require 'shellwords'
|
3
3
|
|
4
4
|
class Dutiful::Storage
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :name, :storage_path
|
6
6
|
|
7
7
|
def initialize(name: nil, path: nil)
|
8
8
|
name ||= 'Custom folder'
|
9
|
-
path ||= Tomlrb.load_file("config/#{name.downcase}.toml", symbolize_keys: true)[:storage][:path]
|
9
|
+
path ||= Tomlrb.load_file("#{Dutiful.dir}/config/#{name.downcase}.toml", symbolize_keys: true)[:storage][:path]
|
10
10
|
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
}
|
11
|
+
@name = name
|
12
|
+
@storage_path = File.expand_path path
|
13
|
+
@path = "#{@storage_path}/dutiful"
|
15
14
|
end
|
16
15
|
|
17
16
|
def available?
|
18
|
-
|
17
|
+
File.exist? storage_path
|
19
18
|
end
|
20
19
|
|
21
20
|
def create_dir(file)
|
22
|
-
|
23
|
-
`mkdir -p #{file_directory_path.shellescape}`
|
24
|
-
end
|
25
|
-
|
26
|
-
def dutiful_path
|
27
|
-
"#{path}/dutiful"
|
21
|
+
FileUtils.mkdir_p File.dirname "#{path}/#{file.path}".shellescape
|
28
22
|
end
|
29
23
|
|
30
24
|
def exist?(file)
|
31
|
-
|
25
|
+
File.exist? "#{path}/#{file.path}"
|
32
26
|
end
|
33
27
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
28
|
+
def path(path = nil)
|
29
|
+
if path
|
30
|
+
"#{@path}/#{path}"
|
31
|
+
else
|
32
|
+
@path
|
33
|
+
end
|
40
34
|
end
|
41
35
|
|
42
36
|
def sync(file)
|
43
37
|
create_dir file
|
44
|
-
|
38
|
+
|
39
|
+
if file.exist?
|
40
|
+
if file.has_backup? && file.backup_timestamp > file.timestamp
|
41
|
+
Rsync.run file.backup_path.shellescape, file.full_path.shellescape
|
42
|
+
else
|
43
|
+
Rsync.run file.full_path.shellescape, file.backup_path.shellescape
|
44
|
+
end
|
45
|
+
else
|
46
|
+
Rsync.run file.backup_path.shellescape, file.full_path.shellescape
|
47
|
+
end
|
45
48
|
end
|
46
49
|
|
47
50
|
def synced?(file)
|
48
|
-
FileUtils.identical? file.full_path, "#{
|
51
|
+
FileUtils.identical? file.full_path, "#{path}/#{file.path}"
|
49
52
|
end
|
50
53
|
|
51
54
|
private
|
52
55
|
|
53
56
|
def self.all
|
54
|
-
Dir.
|
55
|
-
|
56
|
-
|
57
|
-
data = Tomlrb.load_file("config/#{filename}", symbolize_keys: true)[:storage]
|
57
|
+
Dir["#{Dutiful.dir}/config/*.toml"].map do |filename|
|
58
|
+
data = Tomlrb.load_file(filename, symbolize_keys: true)[:storage]
|
58
59
|
Dutiful::Storage.new name: data[:name], path: data[:path]
|
59
60
|
end.compact
|
60
61
|
end
|
data/lib/dutiful/version.rb
CHANGED
data/lib/dutiful.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
module Dutiful
|
2
|
+
def self.dir
|
3
|
+
File.dirname(__dir__)
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
1
7
|
require 'dutiful/application'
|
2
|
-
require 'dutiful/
|
8
|
+
require 'dutiful/application_file'
|
9
|
+
require 'dutiful/commands'
|
3
10
|
require 'dutiful/config'
|
4
|
-
require 'dutiful/file'
|
5
11
|
require 'dutiful/storage'
|
6
12
|
require 'colorize'
|
7
13
|
require 'rsync'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dutiful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Pinto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clamp
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fakefs
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.3'
|
69
97
|
description: Dotfiles manager
|
70
98
|
email: brunoferreirapinto@gmail.com
|
71
99
|
executables:
|
@@ -74,11 +102,23 @@ extensions: []
|
|
74
102
|
extra_rdoc_files: []
|
75
103
|
files:
|
76
104
|
- bin/dutiful
|
105
|
+
- config/dropbox.toml
|
106
|
+
- config/icloud.toml
|
107
|
+
- db/bundler.toml
|
108
|
+
- db/dutiful.toml
|
109
|
+
- db/fish.toml
|
110
|
+
- db/git.toml
|
111
|
+
- db/iterm2.toml
|
112
|
+
- db/tmux.toml
|
113
|
+
- db/vim.toml
|
77
114
|
- lib/dutiful.rb
|
78
115
|
- lib/dutiful/application.rb
|
79
|
-
- lib/dutiful/
|
116
|
+
- lib/dutiful/application_file.rb
|
117
|
+
- lib/dutiful/commands.rb
|
118
|
+
- lib/dutiful/commands/list.rb
|
119
|
+
- lib/dutiful/commands/main.rb
|
120
|
+
- lib/dutiful/commands/sync.rb
|
80
121
|
- lib/dutiful/config.rb
|
81
|
-
- lib/dutiful/file.rb
|
82
122
|
- lib/dutiful/storage.rb
|
83
123
|
- lib/dutiful/version.rb
|
84
124
|
homepage: http://github.com/bpinto/dutiful
|
@@ -104,5 +144,5 @@ rubyforge_project:
|
|
104
144
|
rubygems_version: 2.4.5
|
105
145
|
signing_key:
|
106
146
|
specification_version: 4
|
107
|
-
summary: dutiful-0.0.
|
147
|
+
summary: dutiful-0.0.3
|
108
148
|
test_files: []
|
data/lib/dutiful/command.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'clamp'
|
2
|
-
|
3
|
-
class Dutiful::Command < Clamp::Command
|
4
|
-
option ['-v', '--version'], :flag, 'Show version' do
|
5
|
-
puts "dutiful #{Dutiful::VERSION}"
|
6
|
-
exit 0
|
7
|
-
end
|
8
|
-
|
9
|
-
subcommand 'backup', 'Backup all preference files' do
|
10
|
-
option ['-v', '--verbose'], :flag, 'Verbose mode'
|
11
|
-
|
12
|
-
def execute
|
13
|
-
puts "Storage: #{Dutiful::Config.storage.name}\n\n"
|
14
|
-
|
15
|
-
Dutiful::Application.each do |application|
|
16
|
-
puts "#{application.name}:\n"
|
17
|
-
|
18
|
-
application.sync do |file, result|
|
19
|
-
if result
|
20
|
-
if result.success?
|
21
|
-
puts " #{file.path} ✔".green
|
22
|
-
else
|
23
|
-
puts " #{file.path} ✖ - #{result.error}".red
|
24
|
-
end
|
25
|
-
else
|
26
|
-
puts " #{file.path} does not exist (skipping)".yellow if verbose?
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
subcommand 'list', 'List all preference files' do
|
34
|
-
def execute
|
35
|
-
puts "Storage: #{Dutiful::Config.storage.name}\n\n"
|
36
|
-
|
37
|
-
puts Dutiful::Application.all
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
subcommand 'restore', 'Restore all preference files' do
|
42
|
-
def execute
|
43
|
-
puts 'Not implemented yet'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
subcommand 'which', 'Display the full path to a preference file' do
|
48
|
-
def execute
|
49
|
-
puts 'Not implemented yet'
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/dutiful/file.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Dutiful
|
2
|
-
class File
|
3
|
-
attr_reader :full_path, :path
|
4
|
-
|
5
|
-
def initialize(path)
|
6
|
-
@path = path
|
7
|
-
@full_path = ::File.expand_path "~/#{path}"
|
8
|
-
end
|
9
|
-
|
10
|
-
def exist?
|
11
|
-
::File.exist? @full_path
|
12
|
-
end
|
13
|
-
|
14
|
-
def synced?
|
15
|
-
Dutiful::Config.storage.exist?(self) && Dutiful::Config.storage.synced?(self)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|