Module: Kdeploy::DSL

Included in:
CLI
Defined in:
lib/kdeploy/dsl.rb

Overview

Domain-specific language for defining hosts, roles, and tasks

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



8
9
10
11
12
# File 'lib/kdeploy/dsl.rb', line 8

def self.extended(base)
  base.instance_variable_set(:@kdeploy_hosts, {})
  base.instance_variable_set(:@kdeploy_tasks, {})
  base.instance_variable_set(:@kdeploy_roles, {})
end

Instance Method Details

#add_explicit_hosts(task, hosts) ⇒ Object



154
155
156
157
158
# File 'lib/kdeploy/dsl.rb', line 154

def add_explicit_hosts(task, hosts)
  task[:hosts]&.each do |host|
    hosts.add(host) if kdeploy_hosts.key?(host)
  end
end

#add_role_hosts(task, hosts) ⇒ Object



160
161
162
163
164
165
166
167
168
169
# File 'lib/kdeploy/dsl.rb', line 160

def add_role_hosts(task, hosts)
  task[:roles]&.each do |role|
    role_hosts = kdeploy_roles[role]
    next unless role_hosts

    role_hosts.each do |host|
      hosts.add(host) if kdeploy_hosts.key?(host)
    end
  end
end

#assign_task(task_name, on: nil, roles: nil) ⇒ Object

Assign task to roles or hosts after task definition

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
# File 'lib/kdeploy/dsl.rb', line 43

def assign_task(task_name, on: nil, roles: nil)
  task = kdeploy_tasks[task_name.to_sym]
  raise ArgumentError, "Task #{task_name} not found" unless task

  task[:hosts] = normalize_hosts_option(on) if on
  task[:roles] = normalize_roles_option(roles) if roles
end

#create_task_block(block) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/kdeploy/dsl.rb', line 96

def create_task_block(block)
  lambda {
    @kdeploy_commands = []
    instance_eval(&block)
    @kdeploy_commands
  }
end

#get_task_hosts(task_name) ⇒ Object



140
141
142
143
144
145
146
147
148
# File 'lib/kdeploy/dsl.rb', line 140

def get_task_hosts(task_name)
  task = kdeploy_tasks[task_name]
  return kdeploy_hosts.keys if task_empty?(task)

  hosts = Set.new
  add_explicit_hosts(task, hosts)
  add_role_hosts(task, hosts)
  hosts.to_a
end

#host(name, **options) ⇒ Object



26
27
28
# File 'lib/kdeploy/dsl.rb', line 26

def host(name, **options)
  kdeploy_hosts[name] = options.merge(name: name)
end

#include_tasks(file_path, roles: nil, on: nil) ⇒ Object

Include task file and automatically assign all tasks to specified roles or hosts



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/kdeploy/dsl.rb', line 52

def include_tasks(file_path, roles: nil, on: nil)
  # Resolve relative paths based on the caller's file location
  unless File.absolute_path?(file_path)
    caller_file = caller_locations(1, 1).first.path
    base_dir = File.dirname(File.expand_path(caller_file))
    file_path = File.expand_path(file_path, base_dir)
  end

  # Store tasks before loading
  tasks_before = kdeploy_tasks.keys

  # Load the task file
  module_eval(File.read(file_path), file_path)

  # Get newly added tasks
  tasks_after = kdeploy_tasks.keys
  new_tasks = tasks_after - tasks_before

  # Assign roles/hosts to all new tasks (only if task doesn't already have hosts/roles)
  new_tasks.each do |task_name|
    task = kdeploy_tasks[task_name]
    # Only assign if task doesn't already have hosts or roles defined
    next if task[:hosts] || task[:roles]

    assign_task(task_name, roles: roles, on: on) if roles || on
  end
end

#inventory(&block) ⇒ Object



136
137
138
# File 'lib/kdeploy/dsl.rb', line 136

def inventory(&block)
  instance_eval(&block) if block_given?
end

#kdeploy_hostsObject



14
15
16
# File 'lib/kdeploy/dsl.rb', line 14

def kdeploy_hosts
  @kdeploy_hosts ||= {}
end

#kdeploy_rolesObject



22
23
24
# File 'lib/kdeploy/dsl.rb', line 22

def kdeploy_roles
  @kdeploy_roles ||= {}
end

#kdeploy_tasksObject



18
19
20
# File 'lib/kdeploy/dsl.rb', line 18

def kdeploy_tasks
  @kdeploy_tasks ||= {}
end

#normalize_hosts_option(on) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/kdeploy/dsl.rb', line 80

def normalize_hosts_option(on)
  return on if on.is_a?(Array)

  return [on] if on

  nil
end

#normalize_roles_option(roles) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/kdeploy/dsl.rb', line 88

def normalize_roles_option(roles)
  return roles if roles.is_a?(Array)

  return [roles] if roles

  nil
end

#role(name, hosts) ⇒ Object



30
31
32
# File 'lib/kdeploy/dsl.rb', line 30

def role(name, hosts)
  kdeploy_roles[name] = hosts
end

#run(command, sudo: nil) ⇒ Object



104
105
106
107
# File 'lib/kdeploy/dsl.rb', line 104

def run(command, sudo: nil)
  @kdeploy_commands ||= []
  @kdeploy_commands << { type: :run, command: command, sudo: sudo }
end

#sync(source, destination, ignore: [], delete: false, exclude: []) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/kdeploy/dsl.rb', line 124

def sync(source, destination, ignore: [], delete: false, exclude: [])
  @kdeploy_commands ||= []
  @kdeploy_commands << {
    type: :sync,
    source: source,
    destination: destination,
    ignore: Array(ignore),
    exclude: Array(exclude),
    delete: delete
  }
end

#task(name, on: nil, roles: nil, &block) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/kdeploy/dsl.rb', line 34

def task(name, on: nil, roles: nil, &block)
  kdeploy_tasks[name] = {
    hosts: normalize_hosts_option(on),
    roles: normalize_roles_option(roles),
    block: create_task_block(block)
  }
end

#task_empty?(task) ⇒ Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/kdeploy/dsl.rb', line 150

def task_empty?(task)
  !task || (!task[:hosts] && !task[:roles])
end

#upload(source, destination) ⇒ Object



109
110
111
112
# File 'lib/kdeploy/dsl.rb', line 109

def upload(source, destination)
  @kdeploy_commands ||= []
  @kdeploy_commands << { type: :upload, source: source, destination: destination }
end

#upload_template(source, destination, variables = {}) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/kdeploy/dsl.rb', line 114

def upload_template(source, destination, variables = {})
  @kdeploy_commands ||= []
  @kdeploy_commands << {
    type: :upload_template,
    source: source,
    destination: destination,
    variables: variables
  }
end