dotman-bin 1.0.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.
- checksums.yaml +7 -0
- data/bin/dotman +44 -0
- data/lib/dotman/actions/init.rb +29 -0
- data/lib/dotman/actions/link.rb +46 -0
- data/lib/dotman/checks/host.rb +33 -0
- data/lib/dotman/dotfile.rb +13 -0
- data/lib/dotman/dotfile_configuration.rb +59 -0
- data/lib/dotman/shell/block.rb +11 -0
- data/lib/dotman/shell/command.rb +11 -0
- data/lib/dotman/shell/comparison.rb +15 -0
- data/lib/dotman/shell/condition.rb +19 -0
- data/lib/dotman/shell/statement.rb +29 -0
- data/lib/dotman/shell.rb +43 -0
- data/lib/dotman/version.rb +3 -0
- data/lib/dotman.rb +13 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0e297c042d8398cb7b9602acae6f11a8caebab8687319e365326580ec1caaa50
|
4
|
+
data.tar.gz: c73c57f74294fe4e63e5ab5904f68e8e5ba79016d896ed9432a1ae77bfbca37a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 45e98e9c493425fa1369eeaf3a67e6e322e97bb9a0c99c2de94a1435fcced7da42f4fb4eda4ad180915cf8ba96ad3cbdcaff42f05534731625012281cc24f878
|
7
|
+
data.tar.gz: a7e54d5d57993014b7065192565acd16e499c67cce3e8ebf96b3bb106ab00ee0c0b62e7a7778c6ce6aa4971421a05071a378ebcc2b2775d49b805f2bb72389c4
|
data/bin/dotman
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/dotman'
|
4
|
+
include Dotman
|
5
|
+
|
6
|
+
class Main
|
7
|
+
DOTFILE = 'Dotfile'
|
8
|
+
|
9
|
+
def self.run(opts)
|
10
|
+
unless File.exist?(DOTFILE)
|
11
|
+
puts 'Dotfile not found'.red
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
15
|
+
class << Dotfile
|
16
|
+
load DOTFILE
|
17
|
+
end
|
18
|
+
|
19
|
+
env = {
|
20
|
+
base: File.expand_path(opts['--base']),
|
21
|
+
home: File.expand_path(opts['--home'])
|
22
|
+
}
|
23
|
+
|
24
|
+
puts Dotfile.to_script(env)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
docs = <<~EOF
|
29
|
+
Usage:
|
30
|
+
dotman [options] build
|
31
|
+
|
32
|
+
Options:
|
33
|
+
--base=BASE Dir from where symlinks should be sourced [default: ~/.dotfiles/files]
|
34
|
+
--home=HOME Dir where symlinks should be placed [default: ~]
|
35
|
+
EOF
|
36
|
+
|
37
|
+
begin
|
38
|
+
opts = Docopt::docopt(docs)
|
39
|
+
rescue Docopt::Exit => e
|
40
|
+
puts e.message
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
Main.run(opts)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dotman::Action
|
2
|
+
class Init
|
3
|
+
def to_statement
|
4
|
+
Shell.statement(init, die)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def check_host
|
10
|
+
Shell.comparison('$HOST', '=', '')
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_base
|
14
|
+
Shell.comparison('$BASE_DIR', '=', '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def init
|
18
|
+
Shell.condition([check_host, check_base], :or)
|
19
|
+
end
|
20
|
+
|
21
|
+
def die
|
22
|
+
Shell.block([
|
23
|
+
Shell.echo(:red, 'One or more core environment variables is missing; cannot continue.'),
|
24
|
+
Shell.exit(1)
|
25
|
+
])
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Dotman::Action
|
2
|
+
class Link
|
3
|
+
def initialize(from, to)
|
4
|
+
@from, @to = from, to
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_statement
|
8
|
+
Shell.statement(does_not_exist, create_link, check_link)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
attr_reader :from, :to
|
14
|
+
|
15
|
+
def pair
|
16
|
+
[from, to]
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_link
|
20
|
+
Shell.statement(link_is_set_up, link_set_up, link_not_set_up)
|
21
|
+
end
|
22
|
+
|
23
|
+
def does_not_exist
|
24
|
+
Shell.comparison('$HOME_DIR/' + to, '! -e')
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_link
|
28
|
+
Shell.block([
|
29
|
+
Shell.command('ln -s "$BASE_DIR/%s" "$HOME_DIR/%s"' % pair),
|
30
|
+
Shell.echo(:yellow, 'Link $BASE_DIR/%s → $HOME_DIR/%s created' % pair),
|
31
|
+
])
|
32
|
+
end
|
33
|
+
|
34
|
+
def link_is_set_up
|
35
|
+
Shell.comparison('$(realpath $HOME_DIR/%s)' % to, '=', '$BASE_DIR/' + from)
|
36
|
+
end
|
37
|
+
|
38
|
+
def link_set_up
|
39
|
+
Shell.echo(:green, 'Link $BASE_DIR/%s → $HOME_DIR/%s looking good' % pair)
|
40
|
+
end
|
41
|
+
|
42
|
+
def link_not_set_up
|
43
|
+
Shell.echo(:red, 'Link $BASE_DIR/%s → $HOME_DIR/%s is not set up' % pair)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Dotman::Check
|
2
|
+
class Host
|
3
|
+
def initialize(aliases, hosts, include: true)
|
4
|
+
@aliases, @hosts, @include = aliases, hosts, include
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_comparison
|
8
|
+
Shell.condition(hosts.map { |host| compare(host) }, condition_operator)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def condition_operator
|
14
|
+
if @include then :or else :and end
|
15
|
+
end
|
16
|
+
|
17
|
+
def comparison_operator
|
18
|
+
if @include then '=' else '!=' end
|
19
|
+
end
|
20
|
+
|
21
|
+
def compare(host)
|
22
|
+
Shell.comparison('$HOST', comparison_operator, host)
|
23
|
+
end
|
24
|
+
|
25
|
+
def hosts
|
26
|
+
@hosts.map { |host| get_alias(host) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_alias(target)
|
30
|
+
@aliases[target] || target
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Dotman
|
2
|
+
class DotfileConfiguration
|
3
|
+
def initialize
|
4
|
+
@actions, @host_aliases = [], {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def link(from, to: nil, **args)
|
8
|
+
add_action Action::Link.new(from, to), args
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_script(env)
|
12
|
+
[header(env), actions, footer].join
|
13
|
+
end
|
14
|
+
|
15
|
+
def alias_host(from, to)
|
16
|
+
@host_aliases[from] = to
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def add_action(action, args)
|
22
|
+
@actions << Shell::Statement.new(satisfies_args(args), action.to_statement)
|
23
|
+
end
|
24
|
+
|
25
|
+
def satisfies_args(args)
|
26
|
+
Shell.satisfies_args(@host_aliases, args)
|
27
|
+
end
|
28
|
+
|
29
|
+
def actions
|
30
|
+
actions_list.map(&:to_s).join("\n\n").strip
|
31
|
+
end
|
32
|
+
|
33
|
+
def actions_list
|
34
|
+
[Action::Init.new.to_statement, *@actions]
|
35
|
+
end
|
36
|
+
|
37
|
+
def header(env)
|
38
|
+
return <<~EOF
|
39
|
+
#!/bin/bash
|
40
|
+
set -e
|
41
|
+
|
42
|
+
HOST="$(hostname -s)"
|
43
|
+
BASE_DIR="#{env[:base]}"
|
44
|
+
HOME_DIR="#{env[:home]}"
|
45
|
+
|
46
|
+
echo HOST="#{'$HOST'.bold}"
|
47
|
+
echo BASE_DIR="#{'$BASE_DIR'.bold}"
|
48
|
+
echo HOME_DIR="#{'$HOME_DIR'.bold}"
|
49
|
+
|
50
|
+
echo "#{['Starting...'].shelljoin.green}"
|
51
|
+
|
52
|
+
EOF
|
53
|
+
end
|
54
|
+
|
55
|
+
def footer
|
56
|
+
"\n\n" + 'echo "%s"' % 'Finished.'.green
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Dotman::Shell
|
2
|
+
class Comparison
|
3
|
+
def initialize(operand1, operator, operand2 = nil)
|
4
|
+
@operand1, @operator, @operand2 = operand1, operator, operand2
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
if @operand2.nil?
|
9
|
+
'[ %s "%s" ]' % [@operator, @operand1]
|
10
|
+
else
|
11
|
+
'[ "%s" %s "%s" ]' % [ @operand1, @operator, @operand2 ]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Dotman::Shell
|
2
|
+
class Condition
|
3
|
+
def initialize(conditions, operator = :and)
|
4
|
+
conditions = [conditions] unless conditions.is_a?(Array)
|
5
|
+
@operator = operator
|
6
|
+
@conditions = conditions.compact
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
'( %s )' % @conditions.join(' ' + operator + ' ')
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def operator
|
16
|
+
@operator == :and ? '&&' : '||'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dotman::Shell
|
2
|
+
class Statement
|
3
|
+
def initialize(condition, true_statement, false_statement = nil)
|
4
|
+
@condition = condition
|
5
|
+
@true_statement = true_statement
|
6
|
+
@false_statement = false_statement
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s(level = 0)
|
10
|
+
if @condition.nil?
|
11
|
+
return @true_statement.to_s(level)
|
12
|
+
end
|
13
|
+
|
14
|
+
indent = Shell.indent(level)
|
15
|
+
|
16
|
+
s = indent + "if %s; then\n" % @condition
|
17
|
+
s << "%s\n" % @true_statement.to_s(level + 1)
|
18
|
+
|
19
|
+
if @false_statement
|
20
|
+
s << indent + "else\n"
|
21
|
+
s << "%s\n" % @false_statement.to_s(level + 1)
|
22
|
+
end
|
23
|
+
|
24
|
+
s << indent + 'fi'
|
25
|
+
s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/dotman/shell.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Dotman
|
2
|
+
module Shell
|
3
|
+
def self.satisfies_args(aliases, only: [], except: [])
|
4
|
+
if only.length > 0
|
5
|
+
Check::Host.new(aliases, only, include: true).to_comparison
|
6
|
+
elsif except.length > 0
|
7
|
+
Check::Host.new(aliases, except, include: false).to_comparison
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.echo(colour, msg)
|
12
|
+
command('echo "%s"' % msg.send(colour))
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.exit(code)
|
16
|
+
command('exit ' + code.to_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.indent(level)
|
20
|
+
' ' * (level * 4)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.block(*args)
|
24
|
+
Block.new(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.command(*args)
|
28
|
+
Command.new(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.comparison(*args)
|
32
|
+
Comparison.new(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.condition(*args)
|
36
|
+
Condition.new(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.statement(*args)
|
40
|
+
Statement.new(*args)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/dotman.rb
ADDED
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dotman-bin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- crdx
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-09-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: require_all
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.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.8.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.8.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: docopt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.17.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.17.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '12.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '12.3'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
executables:
|
100
|
+
- dotman
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- bin/dotman
|
105
|
+
- lib/dotman.rb
|
106
|
+
- lib/dotman/actions/init.rb
|
107
|
+
- lib/dotman/actions/link.rb
|
108
|
+
- lib/dotman/checks/host.rb
|
109
|
+
- lib/dotman/dotfile.rb
|
110
|
+
- lib/dotman/dotfile_configuration.rb
|
111
|
+
- lib/dotman/shell.rb
|
112
|
+
- lib/dotman/shell/block.rb
|
113
|
+
- lib/dotman/shell/command.rb
|
114
|
+
- lib/dotman/shell/comparison.rb
|
115
|
+
- lib/dotman/shell/condition.rb
|
116
|
+
- lib/dotman/shell/statement.rb
|
117
|
+
- lib/dotman/version.rb
|
118
|
+
homepage: https://github.com/crdx/dotman
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubygems_version: 3.0.6
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: Run many commands dotman with a colourful overview
|
141
|
+
test_files: []
|