dutiful 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 102221a85fbf0c21b37679ddbdf1cb40bedfdec9
4
+ data.tar.gz: d222a3af107ab1cc13b597179878ca55e146dc8c
5
+ SHA512:
6
+ metadata.gz: 90a5ac97f5783d609c18c5db40b91dcf6496fd95dc4d46d8ff02e2ae8b7fcb182766bb7d280cd4172de7c1c1755c0d78d109890e8ecb45b75728d3ddd5b65c6c
7
+ data.tar.gz: 3ea6eef9dd4b2f100d8c9d216019018a9fbb0e95894648700f258ae0e37210c1d8918e4f43adc1bd7f66e7d0eee3b089adf85d4f7668236c6ec13c2c5a339513
data/bin/dutiful ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'dutiful'
4
+ require 'dutiful/command'
5
+ require 'dutiful/version'
6
+
7
+ Dutiful::Command.run
@@ -0,0 +1,69 @@
1
+ module Dutiful
2
+ class Application
3
+ def initialize(path)
4
+ @path = path
5
+ end
6
+
7
+ def name
8
+ content[:application][:name]
9
+ end
10
+
11
+ def files
12
+ content[:files].map { |file| File.new file[:path] }
13
+ end
14
+
15
+ def exist?
16
+ files.any? &:exist?
17
+ end
18
+
19
+ def sync
20
+ files.each do |file|
21
+ if file.exist?
22
+ result = Dutiful::Command.storage.sync(file) if file.exist?
23
+ yield file, result
24
+ else
25
+ yield file
26
+ end
27
+ end
28
+ end
29
+
30
+ def to_s
31
+ output = "#{name}:\n"
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
44
+
45
+ output
46
+ end
47
+
48
+ def self.all
49
+ Dir.foreach('db').map do |filename|
50
+ next if filename == '.' or filename == '..'
51
+
52
+ application = Dutiful::Application.new "db/#{filename}"
53
+ application if application.exist?
54
+ end.compact
55
+ end
56
+
57
+ def self.each
58
+ return enum_for(:each) unless block_given?
59
+
60
+ all.each { |application| yield application }
61
+ end
62
+
63
+ private
64
+
65
+ def content
66
+ @content ||= Tomlrb.load_file(@path, symbolize_keys: true)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,58 @@
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::Command.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::Command.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
+
53
+ def self.storage
54
+ @storage ||= if Dutiful::Storage::Icloud.available?
55
+ Dutiful::Storage::Icloud
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,18 @@
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::Command.storage.exist?(self) && Dutiful::Command.storage.synced?(self)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ require 'fileutils'
2
+ require 'shellwords'
3
+
4
+ module Dutiful
5
+ module Storage
6
+ class Icloud
7
+ PATH = ::File.expand_path("~/Library/Mobile Documents")
8
+
9
+ def self.available?
10
+ ::File.exist? PATH
11
+ end
12
+
13
+ def self.create_dir(file)
14
+ directory_path = ::File.dirname "#{dir}/#{file.path}"
15
+ `mkdir -p #{directory_path.shellescape}`
16
+ end
17
+
18
+ def self.dir
19
+ "#{PATH}/dutiful"
20
+ end
21
+
22
+ def self.exist?(file)
23
+ ::File.exist? "#{dir}/#{file.path}"
24
+ end
25
+
26
+ def self.name
27
+ 'iCloud'
28
+ end
29
+
30
+ def self.sync(file)
31
+ create_dir file
32
+ Rsync.run file.full_path.shellescape, "#{dir}/#{file.path}".shellescape
33
+ end
34
+
35
+ def self.synced?(file)
36
+ FileUtils.identical? file.full_path, "#{dir}/#{file.path}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1 @@
1
+ require 'dutiful/storages/icloud'
@@ -0,0 +1,3 @@
1
+ module Dutiful
2
+ VERSION = '0.0.1'
3
+ end
data/lib/dutiful.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'dutiful/application'
2
+ require 'dutiful/command'
3
+ require 'dutiful/file'
4
+ require 'dutiful/storages'
5
+ require 'colorize'
6
+ require 'rsync'
7
+ require 'tomlrb'
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dutiful
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bruno Pinto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: clamp
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rsync
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tomlrb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ description: Dotfiles manager
70
+ email: brunoferreirapinto@gmail.com
71
+ executables:
72
+ - dutiful
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - bin/dutiful
77
+ - lib/dutiful.rb
78
+ - lib/dutiful/application.rb
79
+ - lib/dutiful/command.rb
80
+ - lib/dutiful/file.rb
81
+ - lib/dutiful/storages.rb
82
+ - lib/dutiful/storages/icloud.rb
83
+ - lib/dutiful/version.rb
84
+ homepage: http://github.com/bpinto/dutiful
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.4.5
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: dutiful-0.0.1
108
+ test_files: []