central 0.1.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 +7 -0
- data/bin/central +11 -0
- data/lib/central.rb +342 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6144bb903e188d751c09636a68e90ed1e2596edc
|
4
|
+
data.tar.gz: 0d4fa728e247794f61536f81ba80acf93156dd60
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f078f4965f4ecca46af6cf4d7604b942bf92d113653545aa51f29250c6cb9e69539a3d03a6dd60f11ab9f873fc969d11ecfab9702a297d511b627dbea2ba1909
|
7
|
+
data.tar.gz: b3178f8677d21b15a8e6416f3823a3d58431cfa73bd3b6bb33cab1cbfa149d022ff19243caa133796610d3f80581a1d4085b9d369a9f1885a45f500cc8b192df
|
data/bin/central
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# -------------------------------------------------------------------------
|
5
|
+
# # central - dot files manager licensed under LGPLv3 (see LICENSE file) |
|
6
|
+
# # written in Ruby by Dmitry Geurkov (d.geurkov@gmail.com) |
|
7
|
+
# -------------------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'central'
|
10
|
+
|
11
|
+
central(ARGV)
|
data/lib/central.rb
ADDED
@@ -0,0 +1,342 @@
|
|
1
|
+
# -------------------------------------------------------------------------
|
2
|
+
# # central - dot files manager licensed under LGPLv3 (see LICENSE file) |
|
3
|
+
# # written in Ruby by Dmitry Geurkov (d.geurkov@gmail.com) |
|
4
|
+
# -------------------------------------------------------------------------
|
5
|
+
|
6
|
+
require 'erb'
|
7
|
+
require 'socket'
|
8
|
+
|
9
|
+
# get hostname
|
10
|
+
def hostname
|
11
|
+
Socket.gethostname
|
12
|
+
end
|
13
|
+
|
14
|
+
# get operating system
|
15
|
+
def os
|
16
|
+
if RUBY_PLATFORM.include?('linux')
|
17
|
+
return 'linux'
|
18
|
+
elsif RUBY_PLATFORM.include?('darwin')
|
19
|
+
return 'osx'
|
20
|
+
elsif RUBY_PLATFORM.include?('freebsd')
|
21
|
+
return 'freebsd'
|
22
|
+
elsif RUBY_PLATFORM.include?('solaris')
|
23
|
+
return 'solaris'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# run command second time with sudo privileges if it previously failed because of insufficient permissions
|
28
|
+
def sudo(command,sudo=false)
|
29
|
+
if sudo
|
30
|
+
sudo = 'sudo '
|
31
|
+
else
|
32
|
+
sudo = ''
|
33
|
+
end
|
34
|
+
command = sudo+command
|
35
|
+
out = `#{command} 2>&1`
|
36
|
+
# removing line feed
|
37
|
+
if out.length > 0 && out[-1].ord == 10
|
38
|
+
out = out[0...-1]
|
39
|
+
end
|
40
|
+
# removing cariage return
|
41
|
+
if out.length > 0 && out[-1].ord == 13
|
42
|
+
out = out[0...-1]
|
43
|
+
end
|
44
|
+
if out.downcase.end_with?('permission denied')
|
45
|
+
if sudo
|
46
|
+
STDERR.puts "Couldn't execute #{command} due to permission denied\nrun central with sudo privileges"
|
47
|
+
exit 1
|
48
|
+
else
|
49
|
+
out = sudo(command,true)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return out
|
53
|
+
end
|
54
|
+
|
55
|
+
# function used to check that system has all required tools installed
|
56
|
+
def check_tool(name,check)
|
57
|
+
output = sudo("#{check} 2>&1 1>/dev/null").downcase
|
58
|
+
if output.include?('command not found')
|
59
|
+
STDERR.puts "#{name} not found, please install it to use central"
|
60
|
+
exit 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
check_tool('file','file --version')
|
65
|
+
check_tool('grep','grep --version')
|
66
|
+
check_tool('ln','ln --version')
|
67
|
+
check_tool('readlink','readlink --version')
|
68
|
+
check_tool('git','git --version')
|
69
|
+
check_tool('curl','curl --version')
|
70
|
+
|
71
|
+
|
72
|
+
# current working directory
|
73
|
+
def pwd
|
74
|
+
Dir.pwd
|
75
|
+
end
|
76
|
+
|
77
|
+
# absolute path
|
78
|
+
def abs(path)
|
79
|
+
path = File.absolute_path(File.expand_path(path))
|
80
|
+
end
|
81
|
+
|
82
|
+
# change current working directory
|
83
|
+
def chdir(dir)
|
84
|
+
Dir.chdir(abs(dir))
|
85
|
+
end
|
86
|
+
|
87
|
+
# check if file exists
|
88
|
+
def file_exists?(path)
|
89
|
+
path = abs(path)
|
90
|
+
File.file?(path) && File.readable?(path)
|
91
|
+
end
|
92
|
+
|
93
|
+
# check if directory exists
|
94
|
+
def dir_exists?(path)
|
95
|
+
path = abs(path)
|
96
|
+
Dir.exists?(path)
|
97
|
+
end
|
98
|
+
|
99
|
+
# get directory name of a file
|
100
|
+
def file_dir(path)
|
101
|
+
File.dirname(abs(path))
|
102
|
+
end
|
103
|
+
|
104
|
+
# check if file is symlink
|
105
|
+
def symlink?(symlink)
|
106
|
+
File.symlink?(abs(symlink))
|
107
|
+
end
|
108
|
+
|
109
|
+
# get full path of symlink
|
110
|
+
def symlink_path(symlink)
|
111
|
+
sudo("readlink \"#{abs(symlink)}\"")
|
112
|
+
end
|
113
|
+
|
114
|
+
# make directory including intermediate directories
|
115
|
+
def mkdir(path)
|
116
|
+
path = abs(path)
|
117
|
+
unless dir_exists?(path)
|
118
|
+
out = sudo("mkdir -p \"#{path}\"")
|
119
|
+
puts "Created directory: #{path}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# remove file/directory
|
124
|
+
def rm(path,recursive=false)
|
125
|
+
path = abs(path)
|
126
|
+
if recursive
|
127
|
+
recursive = '-R '
|
128
|
+
else
|
129
|
+
recursive = ''
|
130
|
+
end
|
131
|
+
is_dir = dir_exists?(path)
|
132
|
+
is_symlink = symlink?(path)
|
133
|
+
out = sudo("rm #{recursive}-f \"#{path}\"")
|
134
|
+
if is_dir
|
135
|
+
puts "Removed directory: #{path}"
|
136
|
+
elsif is_symlink
|
137
|
+
puts "Removed symlink: #{path}"
|
138
|
+
else
|
139
|
+
puts "Removed file: #{path}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# remove directory recursively
|
144
|
+
def rmdir(path)
|
145
|
+
rm(path,true)
|
146
|
+
end
|
147
|
+
|
148
|
+
# touch file
|
149
|
+
def touch(path)
|
150
|
+
path = abs(path)
|
151
|
+
unless file_exists?(path)
|
152
|
+
out = sudo("touch \"#{path}\"")
|
153
|
+
puts "Touched file: #{path}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# change file permissions
|
158
|
+
def chmod(path,permissions,recursive=false)
|
159
|
+
path = abs(path)
|
160
|
+
if recursive
|
161
|
+
recursive = '-R '
|
162
|
+
else
|
163
|
+
recursive = ''
|
164
|
+
end
|
165
|
+
sudo("chmod #{recursive}#{permissions} \"#{path}\"")
|
166
|
+
end
|
167
|
+
|
168
|
+
# symlink path
|
169
|
+
def symlink(from,to)
|
170
|
+
from = abs(from)
|
171
|
+
to = abs(to)
|
172
|
+
if symlink?(from)
|
173
|
+
if symlink_path(from) != to
|
174
|
+
rm from
|
175
|
+
symlink from, to
|
176
|
+
end
|
177
|
+
elsif file_exists?(from)
|
178
|
+
STDERR.puts "File #{from} exists in place of symlink..."
|
179
|
+
exit 1
|
180
|
+
elsif dir_exists?(from)
|
181
|
+
STDERR.puts "Directory #{from} exists in place of symlink..."
|
182
|
+
exit 1
|
183
|
+
else
|
184
|
+
out = sudo("ln -s \"#{to}\" \"#{from}\"")
|
185
|
+
puts "Created symlink: #{from} → #{to}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# git clone url into a path
|
190
|
+
def git(url,path)
|
191
|
+
path = abs(path)
|
192
|
+
if dir_exists?(path) && dir_exists?("#{path}/.git")
|
193
|
+
cwd = pwd()
|
194
|
+
chdir path
|
195
|
+
out = sudo('git pull')
|
196
|
+
unless out.downcase.include? "already up-to-date"
|
197
|
+
puts out
|
198
|
+
puts "Git repository pulled: #{url} → #{path}"
|
199
|
+
end
|
200
|
+
chdir cwd
|
201
|
+
else
|
202
|
+
out = sudo("git clone #{url} \"#{path}\"")
|
203
|
+
puts out
|
204
|
+
puts "Git repository cloned: #{url} → #{path}"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# download url into a path using curl
|
209
|
+
def curl(url,path)
|
210
|
+
path = abs(path)
|
211
|
+
output = sudo("curl -s \"#{url}\"")
|
212
|
+
unless $?.exitstatus == 0
|
213
|
+
STDERR.puts "Couldn't download file from #{url}..."
|
214
|
+
exit 1
|
215
|
+
end
|
216
|
+
if File.exists?(path) && File.read(path) == output
|
217
|
+
return
|
218
|
+
end
|
219
|
+
File.write(path,output)
|
220
|
+
puts "Downloaded #{url} → #{path}"
|
221
|
+
end
|
222
|
+
|
223
|
+
# read content of a file
|
224
|
+
def read(file)
|
225
|
+
file = abs(file)
|
226
|
+
if file_exists?(file)
|
227
|
+
return File.read(file)
|
228
|
+
else
|
229
|
+
STDERR.puts "Couldn't read file #{file}..."
|
230
|
+
exit 1
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# write content into a file
|
235
|
+
def write(file,content)
|
236
|
+
file = abs(file)
|
237
|
+
File.write(file,content)
|
238
|
+
end
|
239
|
+
|
240
|
+
# source file in sh/bash/zsh script
|
241
|
+
def source(file,source)
|
242
|
+
file = abs(file)
|
243
|
+
source = abs(source)
|
244
|
+
source_line = "source \"#{source}\""
|
245
|
+
out = sudo("grep -Fx '#{source_line}' \"#{file}\"")
|
246
|
+
if out == ""
|
247
|
+
sudo("echo '#{source_line}' >> \"#{file}\"")
|
248
|
+
puts "Added source #{source} line to #{file}"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# list directory content
|
253
|
+
def ls(path,options={})
|
254
|
+
path = abs(path)
|
255
|
+
if options[:dotfiles]
|
256
|
+
dotfiles = '-a '
|
257
|
+
else
|
258
|
+
dotfiles = ''
|
259
|
+
end
|
260
|
+
command = "ls -1 #{dotfiles}\"#{path}\""
|
261
|
+
if options.key?(:grep) && options[:grep].length > 0
|
262
|
+
command += " | grep #{options[:grep]}"
|
263
|
+
end
|
264
|
+
output = sudo(command)
|
265
|
+
if output.downcase.end_with?('no such file or directory')
|
266
|
+
STDERR.puts "Couldn't ls directory #{path}..."
|
267
|
+
exit 1
|
268
|
+
end
|
269
|
+
ls = output.split("\n")
|
270
|
+
dir = true
|
271
|
+
file = true
|
272
|
+
if options.key?(:dir)
|
273
|
+
dir = options[:dir]
|
274
|
+
end
|
275
|
+
if options.key?(:file)
|
276
|
+
file = options[:file]
|
277
|
+
end
|
278
|
+
unless dir
|
279
|
+
ls = ls.keep_if {|f| !File.directory?("#{path}/#{f}") }
|
280
|
+
end
|
281
|
+
unless file
|
282
|
+
ls = ls.keep_if {|f| !File.file?("#{path}/#{f}") }
|
283
|
+
end
|
284
|
+
return ls
|
285
|
+
end
|
286
|
+
|
287
|
+
# process erb template into an output_file
|
288
|
+
def erb(file,output_file = nil)
|
289
|
+
file = abs(file)
|
290
|
+
if output_file == nil
|
291
|
+
if file.end_with?('.erb')
|
292
|
+
output_file = file[0...-4]
|
293
|
+
else
|
294
|
+
output_file = file+'.out'
|
295
|
+
end
|
296
|
+
end
|
297
|
+
if file_exists?(file)
|
298
|
+
output = ERB.new(File.read(file)).result
|
299
|
+
if File.exists?(output_file) && File.read(output_file) == output
|
300
|
+
return
|
301
|
+
end
|
302
|
+
File.write(output_file,output)
|
303
|
+
puts "Processed erb #{file} → #{output_file}"
|
304
|
+
else
|
305
|
+
STDERR.puts "Couldn't process erb file #{file}..."
|
306
|
+
exit 1
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# run configuration.rb file
|
311
|
+
def run(file)
|
312
|
+
cwd = pwd()
|
313
|
+
file = abs(file)
|
314
|
+
unless file_exists?(file)
|
315
|
+
puts "No configuration file: #{file} found"
|
316
|
+
return
|
317
|
+
end
|
318
|
+
puts "Running configuration: "+file
|
319
|
+
file_cwd = file_dir(file)
|
320
|
+
chdir file_cwd
|
321
|
+
load file
|
322
|
+
chdir cwd
|
323
|
+
end
|
324
|
+
|
325
|
+
# run configuration.rb file only if it exists
|
326
|
+
def run_if_exists(file)
|
327
|
+
if file_exists?(file)
|
328
|
+
run file
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
# run central configuration
|
333
|
+
def central(configurations)
|
334
|
+
if configurations.instance_of?(Array) && configurations.length > 0
|
335
|
+
configurations.each {|configuration| run configuration }
|
336
|
+
elsif configurations.instance_of?(String)
|
337
|
+
run configurations
|
338
|
+
else
|
339
|
+
run 'configuration.rb'
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: central
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dmitry Geurkov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: central dotfile management system
|
14
|
+
email: d.geurkov@gmail.com
|
15
|
+
executables:
|
16
|
+
- central
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/central.rb
|
21
|
+
- bin/central
|
22
|
+
homepage: https://github.com/troydm/central
|
23
|
+
licenses:
|
24
|
+
- LGPLv3
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.0.14.1
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: central dotfile management
|
46
|
+
test_files: []
|