dotman-bin 1.0.0

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
+ 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,13 @@
1
+ module Dotman
2
+ class Dotfile
3
+ def self.configure
4
+ config = DotfileConfiguration.new
5
+ @@config = config
6
+ yield config
7
+ end
8
+
9
+ def self.to_script(env)
10
+ @@config.to_script(env)
11
+ end
12
+ end
13
+ 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,11 @@
1
+ module Dotman::Shell
2
+ class Block
3
+ def initialize(commands)
4
+ @commands = commands
5
+ end
6
+
7
+ def to_s(level = 0)
8
+ @commands.map { |command| command.to_s(level) }.join("\n")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Dotman::Shell
2
+ class Command
3
+ def initialize(str)
4
+ @str = str
5
+ end
6
+
7
+ def to_s(level = 0)
8
+ (' ' * (level * 4)) + @str
9
+ end
10
+ end
11
+ 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
+
@@ -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
@@ -0,0 +1,3 @@
1
+ module Dotman
2
+ VERSION = "1.0.0"
3
+ end
data/lib/dotman.rb ADDED
@@ -0,0 +1,13 @@
1
+ Dir.chdir __dir__ do
2
+ require 'bundler/setup'
3
+ require 'require_all'
4
+ require 'colorize'
5
+ require 'docopt'
6
+
7
+ require 'shellwords'
8
+ require 'ostruct'
9
+ require 'socket'
10
+ end
11
+
12
+ module Dotman; end
13
+ require_rel 'dotman'
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: []