Class: Fate::Service

Inherits:
Object
  • Object
show all
Defined in:
lib/fate/service.rb

Constant Summary collapse

SpecificationSchema =
{
  "type" => "object",
  "properties" => {
    "commands" => {
      "type" => "object",
      "required" => true,
      "additionalProperties" => {
        "type" => ["object", "string"]
      }
    },
    "groups" => {
      "type" => "object",
      "additionalProperties" => {
        "type" => ["array"]
      }
    }
  },
  "additionalProperties" => false
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(specification, options) ⇒ Service

Returns a new instance of Service.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/fate/service.rb', line 42

def initialize(specification, options)
  stringify(specification)

  validation = self.class.validate(specification)
  if validation.size > 0
    puts "Invalid specification:"
    puts validation
    exit
  end

  @specification = specification
  @options = options

  @commands = process_commands(@specification["commands"])
  @names = @commands.keys
  @groups = @specification["groups"] || {}
  @completions.merge @groups.keys

  @longest_name = @commands.keys.sort_by {|k| k.size }.last.size
  @logger = Fate::MultiLogger.new(
    :io => STDOUT,
    :width => @longest_name,
    :disable_color => options[:disable_color]
  )
  @output_handlers = Output::Handlers.new(self, options[:output] || {})
end

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



39
40
41
# File 'lib/fate/service.rb', line 39

def commands
  @commands
end

#completionsObject (readonly)

Returns the value of attribute completions.



39
40
41
# File 'lib/fate/service.rb', line 39

def completions
  @completions
end

#loggerObject (readonly)

Returns the value of attribute logger.



40
41
42
# File 'lib/fate/service.rb', line 40

def logger
  @logger
end

#namesObject (readonly)

Returns the value of attribute names.



39
40
41
# File 'lib/fate/service.rb', line 39

def names
  @names
end

#output_handlersObject (readonly)

Returns the value of attribute output_handlers.



40
41
42
# File 'lib/fate/service.rb', line 40

def output_handlers
  @output_handlers
end

#specificationObject (readonly)

Returns the value of attribute specification.



39
40
41
# File 'lib/fate/service.rb', line 39

def specification
  @specification
end

Class Method Details

.validate(spec) ⇒ Object



35
36
37
# File 'lib/fate/service.rb', line 35

def self.validate(spec)
  JSON::Validator.fully_validate(SpecificationSchema, spec)
end

Instance Method Details

#process_commands(hash) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/fate/service.rb', line 82

def process_commands(hash)
  hash = Squeeze::HashTree[hash]

  out = {}
  @completions ||= Set.new
  hash.each_path do |path, value|
    key = path.join(".")
    # add dot-delimited process names to the completions
    (path.size).times do |i|
      @completions << path.slice(0..i).join(".")
    end
    out[key] = value
  end
  out
end

#resolve(specs) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/fate/service.rb', line 98

def resolve(specs)
  command_names = []
  specs.each do |spec|
    names = resolve_commands(spec)
    if names.empty?
      logger.warn "Fate", "No commands found for: #{spec}"
    else
      command_names.concat(names)
    end
  end
  names = command_names.uniq
end

#resolve_commands(name) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/fate/service.rb', line 111

def resolve_commands(name)
  targets = []
  if @commands.has_key?(name)
    targets << name
  elsif @groups.has_key?(name)
    @groups[name].each do |group_name|
      targets += resolve_commands(group_name)
    end
  else
    regex = /^#{name}\..*/
    @commands.each do |cname, _command|
      if cname =~ regex
        targets << cname
      end
    end
  end
  targets
end

#start_order(command_names) ⇒ Object



131
132
133
134
135
136
# File 'lib/fate/service.rb', line 131

def start_order(command_names)
  # presuming the spec file ordered the commands where the dependencies
  # come before the dependers, we should stop the processes in reverse order,
  # then start them back up again in forward order.
  command_names.sort_by {|name| self.names.index(name) }
end

#stop_order(command_names) ⇒ Object



138
139
140
# File 'lib/fate/service.rb', line 138

def stop_order(command_names)
  start_order(command_names).reverse
end

#stringify(hash) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fate/service.rb', line 69

def stringify(hash)
  keys = hash.keys
  keys.each do |key|
    if key.is_a? Symbol
      value = hash.delete(key)
      if value.is_a? Hash
        stringify(value)
      end
      hash[key.to_s] = value
    end
  end
end