dutiful 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []