loom-core 0.0.5 → 0.0.6
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 +4 -4
- data/Gemfile.lock +1 -1
- data/bin/loom +5 -1
- data/lib/loom/config.rb +10 -3
- data/lib/loom/facts/fact_set.rb +7 -1
- data/lib/loom/mods/module.rb +3 -4
- data/lib/loom/pattern/definition_context.rb +1 -1
- data/lib/loom/pattern/dsl.rb +113 -32
- data/lib/loom/pattern/reference_set.rb +7 -7
- data/lib/loom/runner.rb +8 -0
- data/lib/loom/shell/api.rb +2 -0
- data/lib/loom/version.rb +1 -1
- data/lib/loomext/corefacts/system_info_provider.rb +2 -1
- data/lib/loomext/coremods/all.rb +2 -1
- data/lib/loomext/coremods/exec.rb +10 -0
- data/lib/loomext/coremods/git.rb +19 -0
- data/lib/loomext/coremods/package/adapter.rb +1 -1
- data/lib/loomext/coremods/systemd.rb +1 -0
- data/lib/loomext/coremods/systemd/all.rb +2 -0
- data/lib/loomext/coremods/{system.rb → systemd/systemd.rb} +19 -5
- data/lib/loomext/coremods/systemd/systemd_units.rb +69 -0
- data/scripts/harness.sh +1 -0
- data/spec/.loom/error_handling.loom +15 -0
- data/spec/.loom/fail.loom +20 -0
- data/spec/.loom/files.loom +39 -0
- data/spec/.loom/net.loom +21 -0
- data/spec/.loom/pattern_context.loom +78 -0
- data/spec/.loom/pkg.loom +33 -0
- data/spec/.loom/shell.loom +46 -0
- data/spec/.loom/test.loom +73 -0
- data/spec/.loom/user.loom +29 -0
- data/spec/.loom/vms.loom +22 -0
- data/spec/loom/facts/fact_set_spec.rb +57 -0
- data/spec/loom/pattern/dsl_spec.rb +58 -9
- data/spec/loom/shell/harness_blob_spec.rb +1 -1
- data/spec/loom/shell/harness_command_builder_spec.rb +1 -1
- data/spec/loomext/coremods/systemd_spec.rb +31 -0
- data/spec/runloom.sh +12 -19
- data/spec/scripts/harness_spec.rb +1 -1
- data/spec/shared/loom_internals_helper.rb +41 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/systemd.loom +22 -0
- data/spec/test_loom_spec.rb +95 -17
- data/test +2 -0
- metadata +26 -5
- data/spec/test.loom +0 -370
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11bd9487c4e4752e294000493fe1fe04537f97bfcea9385b1cf16e90c2c79a71
|
4
|
+
data.tar.gz: 926227cb27d65b64103dd0f541acb1f523afdfac2df832180450f1aaaff4397f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 687255010d7a4c709cb95b2022151a95175ae88decb368cfac503dd3bfdb24c677abdbd2ef055f16a80a783bad2d24762ab856bf20c085ec08d1f51734c78c01
|
7
|
+
data.tar.gz: b789683f5aefd5a1997536e3f930f143bb7c12fc24be4e40d10fb0147e0c997c5af84798fad9e2da79d3cdbb7f5fe4a854d3f981f6deabe43ff08ab0092e3c68
|
data/Gemfile.lock
CHANGED
data/bin/loom
CHANGED
@@ -65,9 +65,13 @@ EOS
|
|
65
65
|
Loom.configure { |c| c.inventory_all_hosts = flag }
|
66
66
|
end
|
67
67
|
|
68
|
+
global_option "-L", "Adds localhost to the active inventory" do |flag|
|
69
|
+
Loom.configure { |c| c.inventory_hosts << "localhost" }
|
70
|
+
end
|
71
|
+
|
68
72
|
global_option "-H", "--hosts host1,h2,h3", Array,
|
69
73
|
"Adds HOSTS to the active inventory" do |hosts|
|
70
|
-
Loom.configure { |c| c.inventory_hosts
|
74
|
+
Loom.configure { |c| c.inventory_hosts.concat hosts }
|
71
75
|
end
|
72
76
|
|
73
77
|
global_option "-G", "--groups group1,g2,g3", Array,
|
data/lib/loom/config.rb
CHANGED
@@ -12,6 +12,12 @@ module Loom
|
|
12
12
|
CONFIG_VARS = {
|
13
13
|
:loom_search_paths => ['/etc/loom', File.join(ENV['HOME'], '.loom'), './.loom'],
|
14
14
|
:loom_files => ['site.loom'],
|
15
|
+
:loom_file_patterns => ['*.loom'],
|
16
|
+
|
17
|
+
:loomfile_autoloads => [
|
18
|
+
'loomext/corefacts',
|
19
|
+
'loomext/coremods',
|
20
|
+
],
|
15
21
|
|
16
22
|
:inventory_all_hosts => false,
|
17
23
|
:inventory_hosts => [],
|
@@ -49,6 +55,8 @@ module Loom
|
|
49
55
|
end
|
50
56
|
alias_method :dump, :to_yaml # aliased to dump for debugging purposes
|
51
57
|
|
58
|
+
# TODO: disallow CONFIG_VAR properties named after Config methods.... like
|
59
|
+
# files. this is shitty, but I don't want to do a larger change.
|
52
60
|
def files
|
53
61
|
@file_manager
|
54
62
|
end
|
@@ -68,11 +76,10 @@ module Loom
|
|
68
76
|
private
|
69
77
|
class FileManager
|
70
78
|
|
71
|
-
LOOM_FILE_PATTERNS = ["*.loom"]
|
72
|
-
|
73
79
|
def initialize(config)
|
74
80
|
@loom_search_paths = config.loom_search_paths
|
75
81
|
@loom_files = config.loom_files
|
82
|
+
@loom_file_patterns = config.loom_file_patterns
|
76
83
|
end
|
77
84
|
|
78
85
|
def find(glob_patterns)
|
@@ -80,7 +87,7 @@ module Loom
|
|
80
87
|
end
|
81
88
|
|
82
89
|
def loom_files
|
83
|
-
[@loom_files + search_loom_paths(
|
90
|
+
[@loom_files + search_loom_paths(@loom_file_patterns)].flatten.uniq
|
84
91
|
end
|
85
92
|
|
86
93
|
private
|
data/lib/loom/facts/fact_set.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
module Loom::Facts
|
2
2
|
|
3
|
+
class << self
|
4
|
+
def is_empty?(fact_set)
|
5
|
+
EMPTY.equal? fact_set
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
EMPTY = {}
|
4
10
|
class << EMPTY
|
5
11
|
def [](*args)
|
@@ -104,7 +110,7 @@ NB
|
|
104
110
|
v = @fact_map[fact_name.to_sym]
|
105
111
|
dup = v.dup rescue v
|
106
112
|
if dup.nil?
|
107
|
-
EMPTY
|
113
|
+
Loom::Facts::EMPTY
|
108
114
|
else
|
109
115
|
dup
|
110
116
|
end
|
data/lib/loom/mods/module.rb
CHANGED
@@ -19,10 +19,9 @@ module Loom::Mods
|
|
19
19
|
@mods = shell.mod_loader
|
20
20
|
@loom_config = loom_config
|
21
21
|
|
22
|
-
# The action proxy is a facade for the mod provided to
|
23
|
-
# ShellApi (the 'loom' object). The ShellApi calls back to the mod_loader
|
24
|
-
#
|
25
|
-
# action_proxy.
|
22
|
+
# The action proxy is a facade (or is it a proxy? i don't know) for the mod provided to
|
23
|
+
# patterns by the ShellApi (the 'loom' object). The ShellApi calls back to the mod_loader on
|
24
|
+
# method missing which instantiates a new Module object and returns the action_proxy.
|
26
25
|
@action_proxy = self.class.action_proxy self, shell.shell_api
|
27
26
|
@action_args = nil
|
28
27
|
@action_block = nil
|
@@ -45,7 +45,7 @@ module Loom::Pattern
|
|
45
45
|
Loom.log.debug1(self) { "let[:#{let_key}] => #{value}" }
|
46
46
|
|
47
47
|
if value.nil? || value.equal?(Loom::Facts::EMPTY)
|
48
|
-
Loom.log.
|
48
|
+
Loom.log.error "value of let expression[:#{let_key}] is nil"
|
49
49
|
raise NilLetValueError, let_key
|
50
50
|
end
|
51
51
|
scope_object.define_singleton_method(let_key) { value }
|
data/lib/loom/pattern/dsl.rb
CHANGED
@@ -1,36 +1,63 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
1
|
# TODO: DSL extensions:
|
4
|
-
-
|
5
|
-
|
6
|
-
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
2
|
+
# - a way to test and verify pattern execution.... I still don't trust this
|
3
|
+
# enough. this starts with fixing error reporting.
|
4
|
+
# - Pattern+non_idempotent+ marks a pattern as explicitly not idempotent, this
|
5
|
+
# let's additional warnings and checks to be added
|
6
|
+
# - A history module, store a log of each executed command, a hash of the .loom
|
7
|
+
# file, and the requisite facts (the let declarations) for each executed pattern
|
8
|
+
# on the host it executes. /var/log/loom/history? Create this log on startup.
|
9
|
+
# -- add a new set of history commands through the CLI and a history
|
10
|
+
# FactProvider exposing host/loom/pattern_slug execution stats.
|
11
|
+
# - Provide automatic command reversion support with a =Module= DSL that ties in
|
12
|
+
# with local revision history.
|
13
|
+
# -- allow Module actions/mods to define an "undo" command of itself given the
|
14
|
+
# original inputs to the action
|
15
|
+
# -- using the history to pull previous params (let defns) into a revert command.
|
16
|
+
# -- usages of the raw shell, such as `loom.x` and `loom.capture` would be
|
17
|
+
# unsupported. so would accesses to the fact_set in any before/after/pattern
|
18
|
+
# blocks.
|
19
|
+
# -- however patterns that only used let blocks, and used all "revertable"
|
20
|
+
# module methods, could have automatic state reversion and integrity checking
|
21
|
+
# managed.
|
22
|
+
# -- best practices (encouraged through warnings) to be to heavily discourage
|
23
|
+
# uses of loom.execute and loom.capture in .loom files and encourage all
|
24
|
+
# accesses to fact_set be done in let expressions (enforce this maybe?)
|
25
|
+
# -- Later... before/after hooks can ensure the entire loom execution sequence
|
26
|
+
# was "revertable"
|
27
|
+
# - A mechanism to allow mods to register CLI flags and actions. Using an action predicate
|
28
|
+
# mechanisms can add flags at the global or action levels. All CLI flags set config values.
|
29
|
+
# -- Mods can also register for action namespaces similar to git. This is consistent with mod
|
30
|
+
# namespaces on the loom object.
|
31
|
+
# -- Best way is to migrate loom/mods/module and loom/mods/action_proxy into base classes of
|
32
|
+
# themselves. The isolate the shell specific behavior into a subclass of each to preserve the
|
33
|
+
# current behavior. A new "cli" module and "cli" action proxy would enable the implementation.
|
34
|
+
# - Add a phase to the pattern execution sequence to collect calls to factset and loom
|
35
|
+
# objects. Results collected from this ""pre-execute"" can be analyzed for errors, optimization,
|
36
|
+
# success assertions, verification, etc. The loom file then executes in 2 passes, analyze &
|
37
|
+
# execute.
|
38
|
+
# -- pre-fact collection - inject the facts (or loom) object as a recorder (like a mock in record mode)
|
39
|
+
# instead of the factual fact set. no need to change any loom files.
|
40
|
+
# -- only run fact providers which are accessed in the pattern set
|
41
|
+
# -- only load modules accessed in the pattern set
|
42
|
+
# - Replace Pattern "mods" and "mod specs" in Loom::Pattern::ReferenceSet with usages of a builder
|
43
|
+
# instead. Currently the internal data model in ReferenceSet is confusing, but luckily it's the
|
44
|
+
# only client of pattern modules, that have used Loom::Pattern::DSL. Change calls to
|
45
|
+
# DSL#pattern/report/weave (anythin else that creates a pattern) to add a new PatternBuilder to
|
46
|
+
# the module. Use the builder to implement the TODO above ("Add a phase..."). Implement analysis
|
47
|
+
# on the builder.
|
48
|
+
|
49
|
+
=begin
|
27
50
|
|
28
51
|
## .loom File DSL
|
29
52
|
|
30
|
-
See
|
53
|
+
See:
|
54
|
+
* spec/test.loom for a valid .loom file.
|
55
|
+
* spec/loom/pattern/dsl_spec.rb for other examples
|
31
56
|
|
32
|
-
|
33
|
-
|
57
|
+
|
58
|
+
I've tried to take inspriation from several ruby DSLs, including (but not
|
59
|
+
limited to) RSpec, Thor, Commander, Sinatra... so hopefully it feels
|
60
|
+
comfortable.
|
34
61
|
|
35
62
|
Loom::Pattern::DSL is the mixin that defines the declarative API for all .loom
|
36
63
|
file defined modules. It is included into Loom::Pattern by default. The outer
|
@@ -40,7 +67,7 @@ default. Submodules must explicitly include Loom::Pattern, and will receive DSL.
|
|
40
67
|
For example, given the following .loom file:
|
41
68
|
|
42
69
|
``` ~ruby
|
43
|
-
|
70
|
+
pattern :cmd do |loom, facts| puts loom.xe :uptime end
|
44
71
|
|
45
72
|
module Outer
|
46
73
|
|
@@ -76,6 +103,11 @@ file. A ReferenseSet being a collection of references with uniquely named
|
|
76
103
|
slugs. The slug of a reference is computed from the module namespace and
|
77
104
|
instance method name.
|
78
105
|
|
106
|
+
### `report`
|
107
|
+
|
108
|
+
Use `report` to create a pattern that outputs a fact, other value, or result of
|
109
|
+
a block to yaml, json, or any other format.
|
110
|
+
|
79
111
|
### `let`, `before`, and `after`
|
80
112
|
|
81
113
|
Module::Inner, from above, inherits all +let+ declarations from its outer
|
@@ -172,7 +204,7 @@ invoked via Loom::Runner+load+. Expansion happens on read via
|
|
172
204
|
Loom::Pattern::Loader+patterns+, thus the list of patterns is constant
|
173
205
|
throughout all phases of pattern execution.
|
174
206
|
|
175
|
-
#### Pattern Execution
|
207
|
+
#### Pattern Execution Sequence
|
176
208
|
|
177
209
|
Once hosts and patterns are identified in earlier Loom::Runner phases,
|
178
210
|
Loom::Runner+run_internal+, per host, initiates an SSH session and command
|
@@ -210,8 +242,14 @@ TODO
|
|
210
242
|
##
|
211
243
|
|
212
244
|
=end
|
245
|
+
|
246
|
+
require "yaml"
|
247
|
+
require "json"
|
248
|
+
|
213
249
|
module Loom::Pattern
|
214
250
|
|
251
|
+
PatternDefinitionError = Class.new Loom::LoomError
|
252
|
+
|
215
253
|
# TODO: clarify this DSL to only export:
|
216
254
|
# - description
|
217
255
|
# - pattern
|
@@ -246,6 +284,39 @@ module Loom::Pattern
|
|
246
284
|
define_pattern_internal(name, &block)
|
247
285
|
end
|
248
286
|
|
287
|
+
##
|
288
|
+
# @param format[:yaml|:json|:raw] default is :yaml
|
289
|
+
def report(name, format: :yaml, &block)
|
290
|
+
Loom.log.debug1(self) { "defining reporting pattern => #{name}" }
|
291
|
+
define_pattern_internal(name) do |loom, facts|
|
292
|
+
# TODO: I don't like all of this logic in the dsl.
|
293
|
+
result = if block_given?
|
294
|
+
Loom.log.debug(self) { "report[#{name}] from block" }
|
295
|
+
self.instance_exec(loom, facts, &block)
|
296
|
+
elsif !Loom::Facts.is_empty?(facts[name])
|
297
|
+
Loom.log.debug(self) { "report[#{name}] from facts[#{name}]" }
|
298
|
+
facts[name]
|
299
|
+
elsif self.respond_to?(name) && !self.send(name).nil?
|
300
|
+
Loom.log.debug(self) { "report[#{name}] from let{#{name}}" }
|
301
|
+
self.send name
|
302
|
+
else
|
303
|
+
err_msg = "no facts to report for fact[#{name}:#{name.class}]"
|
304
|
+
raise PatternDefinitionError, err_msg
|
305
|
+
end
|
306
|
+
result = result.stdout if result.is_a? Loom::Shell::CmdResult
|
307
|
+
|
308
|
+
puts case format
|
309
|
+
when :yaml then result.to_yaml
|
310
|
+
when :json then result.to_json
|
311
|
+
when :raw then result
|
312
|
+
else
|
313
|
+
err_msg = "invalid report format: #{format.inspect}"
|
314
|
+
err_msg << "valid options: yaml,json,raw"
|
315
|
+
raise PatternDefinitionError, err_msg
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
249
320
|
def weave(name, pattern_slugs)
|
250
321
|
Loom.log.debug1(self) { "defining weave => #{name}" }
|
251
322
|
@weave_slugs ||= {}
|
@@ -300,7 +371,7 @@ module Loom::Pattern
|
|
300
371
|
end
|
301
372
|
|
302
373
|
private
|
303
|
-
def define_pattern_internal(name, &
|
374
|
+
def define_pattern_internal(name, &loom_file_block)
|
304
375
|
@pattern_methods ||= []
|
305
376
|
@pattern_method_map ||= {}
|
306
377
|
@pattern_descriptions ||= {}
|
@@ -312,7 +383,17 @@ module Loom::Pattern
|
|
312
383
|
@pattern_descriptions[method_name] = @next_description
|
313
384
|
@next_description = nil
|
314
385
|
|
315
|
-
|
386
|
+
##
|
387
|
+
# ```ruby
|
388
|
+
# pattern :xyz do |loom, facts|
|
389
|
+
# loom.x :dostuff
|
390
|
+
# end
|
391
|
+
# ```
|
392
|
+
# Patterns declared in the .loom file are defined here:
|
393
|
+
define_method method_name do |loom, facts|
|
394
|
+
Loom.log.debug2(self) { "calling .loom file pattern: #{name}" }
|
395
|
+
self.instance_exec(loom, facts, &loom_file_block)
|
396
|
+
end
|
316
397
|
end
|
317
398
|
|
318
399
|
def hook(scope, &block)
|
@@ -56,22 +56,22 @@ module Loom::Pattern
|
|
56
56
|
using Loom::CoreExt # using demodulize for namespace creation
|
57
57
|
|
58
58
|
class << self
|
59
|
-
def create(ruby_code,
|
59
|
+
def create(ruby_code, source_file)
|
60
60
|
shell_module = Module.new
|
61
61
|
shell_module.include Loom::Pattern
|
62
62
|
# TODO: I think this is my black magic for capturing stacktrace
|
63
63
|
# info... I forget the details. Add documentation.
|
64
|
-
shell_module.module_eval ruby_code,
|
64
|
+
shell_module.module_eval ruby_code, source_file, 1
|
65
65
|
shell_module.namespace ""
|
66
66
|
|
67
|
-
self.new(shell_module,
|
67
|
+
self.new(shell_module, source_file).build
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
def initialize(shell_module,
|
71
|
+
def initialize(shell_module, source_file)
|
72
72
|
@shell_module = shell_module
|
73
73
|
@pattern_mod_specs = pattern_mod_specs
|
74
|
-
@
|
74
|
+
@source_file = source_file
|
75
75
|
end
|
76
76
|
|
77
77
|
def build
|
@@ -106,7 +106,7 @@ module Loom::Pattern
|
|
106
106
|
desc = mod.pattern_description weave_name
|
107
107
|
Loom.log.warn "no descripiton for weave => #{slug}" unless desc
|
108
108
|
|
109
|
-
ExpandingReference.new slug, mod.weave_slugs[weave_name], @
|
109
|
+
ExpandingReference.new slug, mod.weave_slugs[weave_name], @source_file, desc
|
110
110
|
end
|
111
111
|
|
112
112
|
def build_pattern_reference(pattern_name, slug, context, mod)
|
@@ -114,7 +114,7 @@ module Loom::Pattern
|
|
114
114
|
desc = mod.pattern_description pattern_name
|
115
115
|
Loom.log.warn "no descripiton for pattern => #{slug}" unless desc
|
116
116
|
|
117
|
-
Reference.new slug, method, @
|
117
|
+
Reference.new slug, method, @source_file, context, desc
|
118
118
|
end
|
119
119
|
|
120
120
|
def context_for_mod_spec(mod_spec)
|
data/lib/loom/runner.rb
CHANGED
@@ -78,6 +78,10 @@ module Loom
|
|
78
78
|
rescue => e
|
79
79
|
Loom.log.fatal "fatal error => #{e.inspect}"
|
80
80
|
Loom.log.fatal e.backtrace.join "\n\t"
|
81
|
+
|
82
|
+
loom_files = @loom_config.files.loom_files
|
83
|
+
loom_errors = e.backtrace.select { |line| line =~ /(#{loom_files.join("|")})/ }
|
84
|
+
Loom.log.error "Loom file errors: \n\t" + loom_errors.join("\n\t")
|
81
85
|
exit 99
|
82
86
|
end
|
83
87
|
end
|
@@ -114,6 +118,10 @@ module Loom
|
|
114
118
|
pattern_loader = Loom::Pattern::Loader.load @loom_config
|
115
119
|
@pattern_refs = pattern_loader.patterns @pattern_slugs
|
116
120
|
|
121
|
+
@loom_config[:loomfile_autoloads].each do |path|
|
122
|
+
Loom.log.debug { "autoloading: #{path}" }
|
123
|
+
require path
|
124
|
+
end
|
117
125
|
@mod_loader = Loom::Mods::ModLoader.new @loom_config
|
118
126
|
end
|
119
127
|
|
data/lib/loom/shell/api.rb
CHANGED
@@ -19,6 +19,7 @@ module Loom::Shell
|
|
19
19
|
@shell.local.shell_api
|
20
20
|
end
|
21
21
|
|
22
|
+
# This is the entry point for `loom.foo` calls from .loom files.
|
22
23
|
def method_missing(name, *args, &block)
|
23
24
|
Loom.log.debug3(self) { "shell api => #{name} #{args} #{block}" }
|
24
25
|
# TODO: The relationship between shell and mod_loader seems leaky here, a
|
@@ -42,6 +43,7 @@ module Loom::Shell
|
|
42
43
|
def method_missing(name, *args, &block)
|
43
44
|
@cmd_executions.push name
|
44
45
|
@cmd_execution_args.push args
|
46
|
+
self
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
data/lib/loom/version.rb
CHANGED
@@ -83,8 +83,9 @@ module LoomExt::CoreFacts
|
|
83
83
|
facts = {}
|
84
84
|
os_release.each_line do |l|
|
85
85
|
l = l.strip
|
86
|
+
next if l.empty?
|
86
87
|
key, value = l.split("=")
|
87
|
-
unquoted_value = value.gsub(/^"(.+)"$/) { |m| $1 }
|
88
|
+
unquoted_value = value.gsub(/^"(.+)"$/) { |m| $1 } rescue ""
|
88
89
|
facts[key.to_sym] = unquoted_value
|
89
90
|
end
|
90
91
|
facts
|
data/lib/loomext/coremods/all.rb
CHANGED
@@ -7,8 +7,9 @@ require "loom"
|
|
7
7
|
|
8
8
|
require_relative "exec"
|
9
9
|
require_relative "files"
|
10
|
+
require_relative "git"
|
10
11
|
require_relative "net"
|
11
12
|
require_relative "user"
|
12
13
|
require_relative "package/package"
|
13
|
-
require_relative "
|
14
|
+
require_relative "systemd"
|
14
15
|
require_relative "vm/all"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# TODO: rename this file -> oneliners.rb
|
1
2
|
module LoomExt::CoreMods
|
2
3
|
|
3
4
|
FailError = Class.new Loom::ExecutionError
|
@@ -14,8 +15,16 @@ module LoomExt::CoreMods
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
class ExecEcho < Loom::Mods::Module
|
19
|
+
register_mod :exec_echo, :alias => [:xe, :"<<e"] do |*cmd, **opts|
|
20
|
+
shell.capture *cmd, **opts
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
class ChangeDirectory < Loom::Mods::Module
|
18
25
|
register_mod :change_directory, :alias => :cd do |path, &block|
|
26
|
+
# TODO: I think this block binding is to the Module instead of the RunContext. Find out and
|
27
|
+
# fix it.
|
19
28
|
shell.cd path, &block
|
20
29
|
end
|
21
30
|
end
|
@@ -34,6 +43,7 @@ module LoomExt::CoreMods
|
|
34
43
|
|
35
44
|
class Sudo < Loom::Mods::Module
|
36
45
|
register_mod :sudo do |user: :root, cmd: nil, &block|
|
46
|
+
# TODO: ditto re: binding to Module instead of RunContext.
|
37
47
|
shell.sudo user, cmd, &block
|
38
48
|
end
|
39
49
|
end
|