fate 0.2.13 → 0.2.14

Sign up to get free protection for your applications and to get access to all the features.
data/bin/fate CHANGED
@@ -34,7 +34,7 @@ fate = Fate.new(configuration, options)
34
34
 
35
35
 
36
36
  require "fate/repl"
37
- fate.start
37
+ fate.start(ARGV)
38
38
  fate.repl
39
39
 
40
40
 
@@ -1,13 +1,10 @@
1
- require "set"
2
1
 
3
2
  gem "term-ansicolor"
4
- gem "squeeze"
3
+ gem "json-schema"
5
4
  require "term/ansicolor"
6
- require "squeeze/hash_tree"
5
+ require "json-schema"
7
6
 
8
- require "fate/logger"
9
7
  require "fate/service"
10
- require "fate/output"
11
8
  require "fate/process_manager"
12
9
 
13
10
  Thread.abort_on_exception = true
@@ -45,12 +42,18 @@ class Fate
45
42
  end
46
43
  end
47
44
 
48
- def start
49
- if manager.start_group(@service.commands)
50
- logger.green "All commands are running."
51
- true
45
+ def start(command_specs=[])
46
+ if command_specs.size > 0
47
+ command_specs.each do |command_spec|
48
+ self.start_command(command_spec)
49
+ end
52
50
  else
53
- false
51
+ if manager.start_group(@service.commands)
52
+ logger.green "All commands are running."
53
+ true
54
+ else
55
+ false
56
+ end
54
57
  end
55
58
  end
56
59
 
@@ -68,22 +71,28 @@ class Fate
68
71
  start
69
72
  end
70
73
 
71
- def start_command(spec)
72
- names = @service.resolve_commands(spec)
74
+ def start_command(command_spec)
75
+ names = @service.resolve_commands(command_spec)
73
76
  if names.empty?
74
- puts "No commands found for: #{spec}"
77
+ puts "No commands found for: #{command_spec}"
75
78
  else
79
+ commands = {}
76
80
  names.each do |name|
77
81
  command = @service.commands[name]
78
- manager.start_command(name, command)
82
+ commands[name] = command
83
+ end
84
+ if manager.start_group(commands)
85
+ logger.green "All commands in '#{command_spec}' running."
86
+ else
87
+ logger.red "Failed to start '#{command_spec}'."
79
88
  end
80
89
  end
81
90
  end
82
91
 
83
- def stop_command(spec)
84
- names = @service.resolve_commands(spec)
92
+ def stop_command(command_spec)
93
+ names = @service.resolve_commands(command_spec)
85
94
  if names.empty?
86
- puts "No commands found for: #{spec}"
95
+ puts "No commands found for: #{command_spec}"
87
96
  else
88
97
  names.each do |name|
89
98
  manager.stop_command(name)
@@ -18,16 +18,17 @@ class Fate
18
18
  @names_by_pid = {}
19
19
  @pids_by_name = {}
20
20
  at_exit do
21
- stop
21
+ shutdown
22
22
  end
23
23
  end
24
24
 
25
- def stop
25
+ def shutdown
26
26
  @mutex.synchronize do
27
27
  @names_by_pid.each do |pid, name|
28
28
  kill(name)
29
29
  end
30
30
  end
31
+ exit(1)
31
32
  end
32
33
 
33
34
  def start_group(hash)
@@ -36,7 +37,7 @@ class Fate
36
37
  start_command(name, command) unless @down_in_flames
37
38
  end
38
39
 
39
- until @threads.size == hash.size
40
+ until hash.keys.all? { |key| @threads[key] }
40
41
  return false if @down_in_flames
41
42
  sleep 0.1
42
43
  end
@@ -139,7 +140,7 @@ class Fate
139
140
  end
140
141
  logger.info "Shutting down all processes."
141
142
 
142
- stop
143
+ shutdown
143
144
  end
144
145
 
145
146
 
@@ -12,9 +12,8 @@ class Fate
12
12
  puts "* Available commands: " << commands.sort.join(" ")
13
13
  end
14
14
 
15
- command("quit", :alias => "q") do
16
- exit
17
- end
15
+ command("quit", :alias => "q") { exit }
16
+ command("exit") { exit }
18
17
 
19
18
  command("stop") do
20
19
  self.stop
@@ -1,20 +1,76 @@
1
+ require "set"
2
+
3
+ gem "squeeze"
4
+ require "squeeze/hash_tree"
5
+
6
+ require "fate/logger"
7
+ require "fate/output"
8
+
1
9
  class Fate
2
10
 
3
11
  class Service
4
12
 
5
- attr_reader :longest_name, :names, :commands, :completions, :specification
13
+ SpecificationSchema = {
14
+ "type" => "object",
15
+ "properties" => {
16
+ "commands" => {
17
+ "type" => "object",
18
+ "additionalProperties" => {
19
+ "type" => ["object", "string"]
20
+ }
21
+ },
22
+ "groups" => {
23
+ "type" => "object",
24
+ "additionalProperties" => {
25
+ "type" => ["array"]
26
+ }
27
+ }
28
+ },
29
+ "additionalProperties" => false
30
+ }
31
+
32
+ def self.validate(spec)
33
+ JSON::Validator.fully_validate(SpecificationSchema, spec)
34
+ end
35
+
36
+ attr_reader :names, :commands, :completions, :specification
6
37
  attr_reader :output_handlers, :logger
7
38
  def initialize(specification, options)
39
+ stringify(specification)
40
+
41
+ validation = self.class.validate(specification)
42
+ if validation.size > 0
43
+ puts "Invalid specification:"
44
+ puts validation
45
+ exit
46
+ end
47
+
8
48
  @specification = specification
9
49
  @options = options
10
50
 
11
- @commands = process_commands(@specification[:commands])
51
+ @commands = process_commands(@specification["commands"])
12
52
  @names = @commands.keys
53
+ @groups = @specification["groups"] || {}
54
+ @completions.merge @groups.keys
55
+
13
56
  @longest_name = @commands.keys.sort_by {|k| k.size }.last.size
14
57
  @logger = Fate::MultiLogger.new(:io => STDOUT, :width => @longest_name)
15
58
  @output_handlers = Output::Handlers.new(self, options[:output] || {})
16
59
  end
17
60
 
61
+ def stringify(hash)
62
+ keys = hash.keys
63
+ keys.each do |key|
64
+ if key.is_a? Symbol
65
+ value = hash.delete(key)
66
+ if value.is_a? Hash
67
+ stringify(value)
68
+ end
69
+ hash[key.to_s] = value
70
+ end
71
+ end
72
+ end
73
+
18
74
  def process_commands(hash)
19
75
  hash = Squeeze::HashTree[hash]
20
76
 
@@ -35,6 +91,8 @@ class Fate
35
91
  targets = []
36
92
  if @commands.has_key?(name)
37
93
  targets << name
94
+ elsif @groups.has_key?(name)
95
+ targets += @groups[name]
38
96
  else
39
97
  @commands.each do |cname, _command|
40
98
  if cname.split(".").first == name
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.13
4
+ version: 0.2.14
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-01 00:00:00.000000000 Z
12
+ date: 2012-11-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -75,6 +75,22 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: 1.0.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: json-schema
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.0.10
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.0.10
78
94
  description:
79
95
  email:
80
96
  executables: