archfiend 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.github/PULL_REQUEST_TEMPLATE.md +18 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +323 -0
  6. data/.travis.yml +11 -0
  7. data/CHANGES.md +12 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +7 -0
  10. data/Gemfile.lock +122 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +114 -0
  13. data/ROADMAP.md +11 -0
  14. data/Rakefile +6 -0
  15. data/archfiend.gemspec +35 -0
  16. data/bin/console +14 -0
  17. data/bin/setup +8 -0
  18. data/exe/archfiend +4 -0
  19. data/lib/archfiend.rb +18 -0
  20. data/lib/archfiend/application.rb +132 -0
  21. data/lib/archfiend/cli.rb +9 -0
  22. data/lib/archfiend/generators/daemon.rb +144 -0
  23. data/lib/archfiend/generators/daemon/templates/.rspec +4 -0
  24. data/lib/archfiend/generators/daemon/templates/.rubocop.yml +323 -0
  25. data/lib/archfiend/generators/daemon/templates/Gemfile.tt +32 -0
  26. data/lib/archfiend/generators/daemon/templates/README.md.tt +23 -0
  27. data/lib/archfiend/generators/daemon/templates/Rakefile.tt +13 -0
  28. data/lib/archfiend/generators/daemon/templates/app/clockwork/clockwork.rb.tt +14 -0
  29. data/lib/archfiend/generators/daemon/templates/app/models/application_record.rb +3 -0
  30. data/lib/archfiend/generators/daemon/templates/app/subprocess_loops/foo_subprocess_loop.rb +13 -0
  31. data/lib/archfiend/generators/daemon/templates/app/thread_loops/bar_thread_loop.rb +8 -0
  32. data/lib/archfiend/generators/daemon/templates/bin/console +3 -0
  33. data/lib/archfiend/generators/daemon/templates/bin/start.tt +6 -0
  34. data/lib/archfiend/generators/daemon/templates/config/application.rb.tt +27 -0
  35. data/lib/archfiend/generators/daemon/templates/config/boot.rb.tt +3 -0
  36. data/lib/archfiend/generators/daemon/templates/config/daemon.rb.tt +18 -0
  37. data/lib/archfiend/generators/daemon/templates/config/database.yml.example.tt +26 -0
  38. data/lib/archfiend/generators/daemon/templates/config/environment.rb.tt +4 -0
  39. data/lib/archfiend/generators/daemon/templates/config/settings.yml.tt +8 -0
  40. data/lib/archfiend/generators/daemon/templates/config/settings/development.yml.tt +2 -0
  41. data/lib/archfiend/generators/daemon/templates/config/settings/production.yml.tt +2 -0
  42. data/lib/archfiend/generators/daemon/templates/config/settings/staging.yml.tt +5 -0
  43. data/lib/archfiend/generators/daemon/templates/config/settings/test.yml.tt +0 -0
  44. data/lib/archfiend/generators/daemon/templates/db/migrate/.gitkeep +0 -0
  45. data/lib/archfiend/generators/daemon/templates/lib/tasks/.gitkeep +0 -0
  46. data/lib/archfiend/generators/daemon/templates/log/.gitkeep +0 -0
  47. data/lib/archfiend/generators/daemon/templates/spec/factories/.gitkeep +0 -0
  48. data/lib/archfiend/generators/daemon/templates/spec/models/.gitkeep +0 -0
  49. data/lib/archfiend/generators/daemon/templates/spec/spec_helper.rb +43 -0
  50. data/lib/archfiend/generators/daemon/templates/spec/subprocess_loops/foo_subprocess_loop_spec.rb +5 -0
  51. data/lib/archfiend/generators/daemon/templates/spec/support/factory_bot.rb +9 -0
  52. data/lib/archfiend/generators/daemon/templates/spec/support/timecop.rb +9 -0
  53. data/lib/archfiend/generators/daemon/templates/spec/thread_loops/bar_thread_loop_spec.rb +5 -0
  54. data/lib/archfiend/generators/daemon/templates/tmp/.gitkeep +0 -0
  55. data/lib/archfiend/generators/extensions.rb +119 -0
  56. data/lib/archfiend/generators/options.rb +51 -0
  57. data/lib/archfiend/generators/utils.rb +37 -0
  58. data/lib/archfiend/logging.rb +38 -0
  59. data/lib/archfiend/logging/base_formatter.rb +35 -0
  60. data/lib/archfiend/logging/default_formatter.rb +12 -0
  61. data/lib/archfiend/logging/json_formatter.rb +21 -0
  62. data/lib/archfiend/logging/multi_logger.rb +31 -0
  63. data/lib/archfiend/shared_loop/runnable.rb +26 -0
  64. data/lib/archfiend/subprocess_loop.rb +46 -0
  65. data/lib/archfiend/thread_loop.rb +35 -0
  66. data/lib/archfiend/version.rb +3 -0
  67. data/scripts/travis/install +13 -0
  68. data/scripts/travis/script +43 -0
  69. metadata +280 -0
@@ -0,0 +1,51 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+
4
+ module Archfiend
5
+ module Generators
6
+ class Options
7
+ extend Forwardable
8
+ SETTINGS_FILE = '.archfiend'.freeze
9
+
10
+ def_delegators :@options, :extensions
11
+
12
+ def initialize(args)
13
+ default_args = parse_archfiend_file || []
14
+ @options = parse_options(default_args + args)
15
+ end
16
+
17
+ private
18
+
19
+ def parse_options(args)
20
+ options = OpenStruct.new
21
+ options.extensions = Set.new
22
+
23
+ opt_parser = OptionParser.new do |opts|
24
+ opts.on '-e', '--extension EXTENSION_NAME', 'Include the specified Archfiend extension' do |extension_name|
25
+ options.extensions << extension_name
26
+ end
27
+ end
28
+
29
+ opt_parser.parse!(args)
30
+ options
31
+ end
32
+
33
+ # Look if there is a default settings file in pwd or all the way up and read it
34
+ #
35
+ # @return [Array<String>, nil] A list of options from the options file or nil when no file
36
+ def parse_archfiend_file
37
+ settings_file = Utils.find_file(SETTINGS_FILE)
38
+
39
+ return unless settings_file
40
+
41
+ unless File.readable?(settings_file)
42
+ puts "Skipping #{settings_file}, not readable"
43
+ return
44
+ end
45
+
46
+ puts "Reading #{settings_file} for default options"
47
+ File.read(settings_file).split
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,37 @@
1
+ module Archfiend
2
+ module Generators
3
+ module Utils
4
+ class << self
5
+ # Methods borrowed from Bundler
6
+ # source: bundler/lib/bundler/shared_helpers.rb
7
+ def find_file(*names)
8
+ search_up(*names) do |filename|
9
+ return filename if File.file?(filename)
10
+ end
11
+ end
12
+
13
+ def find_directory(*names)
14
+ search_up(*names) do |dirname|
15
+ return dirname if File.directory?(dirname)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def search_up(*names)
22
+ previous = nil
23
+ current = File.expand_path(Pathname.pwd).untaint
24
+
25
+ until !File.directory?(current) || current == previous
26
+ names.each do |name|
27
+ filename = File.join(current, name)
28
+ yield filename
29
+ end
30
+ previous = current
31
+ current = File.expand_path('..', current)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ require 'logger'
2
+ require 'oj'
3
+
4
+ module Archfiend
5
+ class Logging
6
+ class << self
7
+ # @param environment [String|Symbol] Current running environment, ex. :development
8
+ # @param log_directory [String,Pathname] Directory in which the logfile is supposed to live
9
+ # @param quiet [Boolean] Whether the STDOUT development output should be suppressed
10
+ # @return [MultiLogger] A multiplexer for up to two loggers
11
+ def create(environment, log_directory, quiet = false)
12
+ environment = environment.to_sym
13
+ loggers = [file_logger(environment, log_directory)]
14
+ loggers << stdio_logger if environment == :development && !quiet
15
+
16
+ MultiLogger.new(*loggers)
17
+ end
18
+
19
+ private
20
+
21
+ def file_logger(environment, log_directory)
22
+ log_name = File.join(log_directory, "#{environment}.log")
23
+ file_logger = Logger.new(log_name, 'daily')
24
+ file_logger.formatter = JSONFormatter.new
25
+ file_logger
26
+ end
27
+
28
+ def stdio_logger
29
+ stdout_io = IO.try_convert(STDOUT)
30
+ stdout_io.sync = true
31
+ stdout_logger = Logger.new(stdout_io)
32
+
33
+ stdout_logger.formatter = DefaultFormatter.new
34
+ stdout_logger
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ module Archfiend
2
+ class Logging
3
+ class BaseFormatter
4
+ STACK_ENTRIES_TO_SKIP = 9 # How many stack frames to exclude from the backtrace
5
+ SEVERITY_STACK_ENTRIES_COUNT = { # How many stack frames to include
6
+ 'FATAL' => 10,
7
+ 'ERROR' => 10,
8
+ 'WARN' => 5,
9
+ 'INFO' => 2,
10
+ 'DEBUG' => 2,
11
+ 'UNKNOWN' => 2
12
+ }.freeze
13
+
14
+ private
15
+
16
+ def description_and_backtrace(severity, msg)
17
+ description = nil
18
+ backtrace = nil
19
+
20
+ if msg.is_a?(Hash)
21
+ description = msg[:message]
22
+ backtrace = msg[:backtrace]&.slice(0, SEVERITY_STACK_ENTRIES_COUNT[severity])
23
+ else
24
+ description = msg
25
+ end
26
+ backtrace ||= caller.slice(STACK_ENTRIES_TO_SKIP - 1, SEVERITY_STACK_ENTRIES_COUNT[severity])
27
+ [description, backtrace]
28
+ end
29
+
30
+ def tid
31
+ Thread.current[:tid] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ module Archfiend
2
+ class Logging
3
+ # Simple formatter that includes both PID and a unique thread id
4
+ class DefaultFormatter < BaseFormatter
5
+ def call(severity, datetime, _progname, msg)
6
+ description, _backtrace = description_and_backtrace(severity, msg)
7
+
8
+ "#{datetime.utc.iso8601(3)} #{::Process.pid} TID-#{tid} #{severity}: #{description}\n"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Archfiend
2
+ class Logging
3
+ # A JSON log formatter class, returns each entry as a JSON line
4
+ class JSONFormatter < BaseFormatter
5
+ def call(severity, datetime, progname, msg)
6
+ description, backtrace = description_and_backtrace(severity, msg)
7
+ log_hash = {
8
+ '@timestamp': datetime.utc.iso8601(3),
9
+ loglevel: severity&.downcase,
10
+ pid: ::Process.pid,
11
+ tid: tid,
12
+ type: :archfiend,
13
+ message: description,
14
+ backtrace: backtrace,
15
+ app: progname
16
+ }
17
+ Oj.dump(log_hash, mode: :compat) + "\n"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module Archfiend
2
+ class Logging
3
+ # A basic class that forwards all log calls to loggers it was initialized with.
4
+ class MultiLogger < BasicObject
5
+ attr_reader :loggers
6
+
7
+ # @param loggers [Array<Logger>] A list of loggers to forward messages to
8
+ def initialize(*loggers)
9
+ @loggers = loggers.flatten
10
+ @responding_loggers = {}
11
+ end
12
+
13
+ private
14
+
15
+ # @return [Object] The return value is forwarded from the first logger that responds to the method_name
16
+ def method_missing(method_name, *args)
17
+ return super unless responding_loggers(method_name).any?
18
+
19
+ responding_loggers(method_name).map { |l| l.public_send(method_name, *args) }.first
20
+ end
21
+
22
+ def respond_to_missing?(symbol, include_private = false)
23
+ responding_loggers(method_name).any? || super
24
+ end
25
+
26
+ def responding_loggers(method_name)
27
+ @responding_loggers[method_name.to_sym] ||= @loggers.select { |l| l.respond_to?(method_name) }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Archfiend
2
+ module SharedLoop
3
+ module Runnable
4
+ def run
5
+ loop do
6
+ begin
7
+ wrap_iterate
8
+ rescue => e
9
+ log_exception(e)
10
+ sleep self.class.const_get('EXCEPTION_DELAY')
11
+ end
12
+ end
13
+ end
14
+
15
+ def log_exception(exception)
16
+ logger.error(message: exception.to_s, backtrace: exception.backtrace)
17
+ end
18
+
19
+ private
20
+
21
+ def wrap_iterate
22
+ iterate
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module Archfiend
2
+ class SubprocessLoop
3
+ extend Forwardable
4
+ include SharedLoop::Runnable
5
+
6
+ EXCEPTION_DELAY = 1 # Seconds to sleep for after rescuing recoverable exception
7
+
8
+ def_delegator :app, :logger
9
+
10
+ attr_accessor :app
11
+
12
+ class << self
13
+ attr_reader :subclasses, :subprocess_pids
14
+
15
+ def inherited(child_class)
16
+ @subclasses ||= []
17
+ @subclasses.push(child_class)
18
+ @subprocess_pids ||= [] # rubocop:disable Naming/MemoizedInstanceVariableName
19
+ end
20
+
21
+ def start_all(app)
22
+ (subclasses || []).each do |subclass|
23
+ process_id = fork do
24
+ instance = subclass.new
25
+ instance.app = app
26
+ app.logger.info "Starting subprocess #{subclass}"
27
+ instance.run
28
+ end
29
+ @subprocess_pids << process_id
30
+ Process.detach(process_id)
31
+ end
32
+ end
33
+
34
+ def kill_all
35
+ return if !@subprocess_pids || @subprocess_pids.empty?
36
+ @subprocess_pids.each do |spid|
37
+ begin
38
+ Process.kill('TERM', spid)
39
+ rescue Errno::ESRCH, Errno::EPERM # rubocop:disable Lint/HandleExceptions
40
+ # The list might contain some stale pids, if any of subprocesses terminated early
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ module Archfiend
2
+ class ThreadLoop
3
+ extend Forwardable
4
+ include SharedLoop::Runnable
5
+
6
+ EXCEPTION_DELAY = 1 # Seconds to sleep for after rescuing recoverable exception
7
+
8
+ def_delegator :app, :logger
9
+
10
+ attr_accessor :app
11
+
12
+ class << self
13
+ attr_reader :subclasses
14
+
15
+ # Collects all subclasses in the class instance variable
16
+ def inherited(child_class)
17
+ @subclasses ||= []
18
+ @subclasses.push(child_class)
19
+ end
20
+
21
+ def start_all(app)
22
+ (subclasses || []).map do |thread_loop_class|
23
+ th = Thread.new do
24
+ instance = thread_loop_class.new
25
+ instance.app = app
26
+ app.logger.info "Starting thread #{thread_loop_class}"
27
+ instance.run
28
+ end
29
+ th[:name] = thread_loop_class.name
30
+ th
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Archfiend
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This script handles the Travis build execution in the 'install' phase.
4
+ # It runs Bundler.
5
+
6
+ require 'pathname'
7
+ require 'fileutils'
8
+
9
+ def system!(*args)
10
+ system(*args) || abort("\n== Command #{args} failed ==")
11
+ end
12
+
13
+ system('bundle check --gemfile=Gemfile') || system!('bundle install --jobs=3 --retry=3 --gemfile=Gemfile')
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This script handles the Travis build execution in the 'script' phase.
4
+ # It runs RuboCop and RSpec.
5
+
6
+ require 'pathname'
7
+ require 'fileutils'
8
+
9
+ archfiend_root = Pathname.new File.expand_path(File.join('..', '..'), __dir__)
10
+
11
+ def system!(*args)
12
+ system(*args) || abort("\n== Command #{args} failed ==")
13
+ end
14
+
15
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rubocop')
16
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rspec')
17
+
18
+ system!('mkdir testing')
19
+
20
+ FileUtils.chdir(archfiend_root.join('testing')) do
21
+ system!('bundle exec archfiend new foo_bar')
22
+ end
23
+
24
+ database_yml = '
25
+ test:
26
+ adapter: postgresql
27
+ database: foo_bar_test
28
+ '
29
+
30
+ File.open(archfiend_root.join('testing', 'foo_bar', 'config', 'database.yml'), 'w') do |f|
31
+ f.puts(database_yml)
32
+ end
33
+
34
+ FileUtils.chdir(File.join('testing', 'foo_bar')) do
35
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rake db:create')
36
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rake db:migrate')
37
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rspec')
38
+ system!('BUNDLE_GEMFILE=Gemfile bundle exec rubocop')
39
+
40
+ system!('BUNDLE_GEMFILE=Gemfile bin/start -d')
41
+ sleep(1)
42
+ system!('ps -o pid= -p `cat foo_bar.pid`')
43
+ end
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: archfiend
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maciek Dubiński
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.15'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.15'
55
+ - !ruby/object:Gem::Dependency
56
+ name: config
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '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'
69
+ - !ruby/object:Gem::Dependency
70
+ name: oj
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.21'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.21'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: thor
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: A tool to simplify creation and development of Ruby daemons.
182
+ email:
183
+ - maciek@dubinski.net
184
+ executables:
185
+ - archfiend
186
+ extensions: []
187
+ extra_rdoc_files: []
188
+ files:
189
+ - ".github/PULL_REQUEST_TEMPLATE.md"
190
+ - ".gitignore"
191
+ - ".rspec"
192
+ - ".rubocop.yml"
193
+ - ".travis.yml"
194
+ - CHANGES.md
195
+ - CODE_OF_CONDUCT.md
196
+ - Gemfile
197
+ - Gemfile.lock
198
+ - LICENSE.txt
199
+ - README.md
200
+ - ROADMAP.md
201
+ - Rakefile
202
+ - archfiend.gemspec
203
+ - bin/console
204
+ - bin/setup
205
+ - exe/archfiend
206
+ - lib/archfiend.rb
207
+ - lib/archfiend/application.rb
208
+ - lib/archfiend/cli.rb
209
+ - lib/archfiend/generators/daemon.rb
210
+ - lib/archfiend/generators/daemon/templates/.rspec
211
+ - lib/archfiend/generators/daemon/templates/.rubocop.yml
212
+ - lib/archfiend/generators/daemon/templates/Gemfile.tt
213
+ - lib/archfiend/generators/daemon/templates/README.md.tt
214
+ - lib/archfiend/generators/daemon/templates/Rakefile.tt
215
+ - lib/archfiend/generators/daemon/templates/app/clockwork/clockwork.rb.tt
216
+ - lib/archfiend/generators/daemon/templates/app/models/application_record.rb
217
+ - lib/archfiend/generators/daemon/templates/app/subprocess_loops/foo_subprocess_loop.rb
218
+ - lib/archfiend/generators/daemon/templates/app/thread_loops/bar_thread_loop.rb
219
+ - lib/archfiend/generators/daemon/templates/bin/console
220
+ - lib/archfiend/generators/daemon/templates/bin/start.tt
221
+ - lib/archfiend/generators/daemon/templates/config/application.rb.tt
222
+ - lib/archfiend/generators/daemon/templates/config/boot.rb.tt
223
+ - lib/archfiend/generators/daemon/templates/config/daemon.rb.tt
224
+ - lib/archfiend/generators/daemon/templates/config/database.yml.example.tt
225
+ - lib/archfiend/generators/daemon/templates/config/environment.rb.tt
226
+ - lib/archfiend/generators/daemon/templates/config/settings.yml.tt
227
+ - lib/archfiend/generators/daemon/templates/config/settings/development.yml.tt
228
+ - lib/archfiend/generators/daemon/templates/config/settings/production.yml.tt
229
+ - lib/archfiend/generators/daemon/templates/config/settings/staging.yml.tt
230
+ - lib/archfiend/generators/daemon/templates/config/settings/test.yml.tt
231
+ - lib/archfiend/generators/daemon/templates/db/migrate/.gitkeep
232
+ - lib/archfiend/generators/daemon/templates/lib/tasks/.gitkeep
233
+ - lib/archfiend/generators/daemon/templates/log/.gitkeep
234
+ - lib/archfiend/generators/daemon/templates/spec/factories/.gitkeep
235
+ - lib/archfiend/generators/daemon/templates/spec/models/.gitkeep
236
+ - lib/archfiend/generators/daemon/templates/spec/spec_helper.rb
237
+ - lib/archfiend/generators/daemon/templates/spec/subprocess_loops/foo_subprocess_loop_spec.rb
238
+ - lib/archfiend/generators/daemon/templates/spec/support/factory_bot.rb
239
+ - lib/archfiend/generators/daemon/templates/spec/support/timecop.rb
240
+ - lib/archfiend/generators/daemon/templates/spec/thread_loops/bar_thread_loop_spec.rb
241
+ - lib/archfiend/generators/daemon/templates/tmp/.gitkeep
242
+ - lib/archfiend/generators/extensions.rb
243
+ - lib/archfiend/generators/options.rb
244
+ - lib/archfiend/generators/utils.rb
245
+ - lib/archfiend/logging.rb
246
+ - lib/archfiend/logging/base_formatter.rb
247
+ - lib/archfiend/logging/default_formatter.rb
248
+ - lib/archfiend/logging/json_formatter.rb
249
+ - lib/archfiend/logging/multi_logger.rb
250
+ - lib/archfiend/shared_loop/runnable.rb
251
+ - lib/archfiend/subprocess_loop.rb
252
+ - lib/archfiend/thread_loop.rb
253
+ - lib/archfiend/version.rb
254
+ - scripts/travis/install
255
+ - scripts/travis/script
256
+ homepage: https://github.com/toptal/archfiend
257
+ licenses:
258
+ - MIT
259
+ metadata: {}
260
+ post_install_message:
261
+ rdoc_options: []
262
+ require_paths:
263
+ - lib
264
+ required_ruby_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
269
+ required_rubygems_version: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ requirements: []
275
+ rubyforge_project:
276
+ rubygems_version: 2.7.6
277
+ signing_key:
278
+ specification_version: 4
279
+ summary: A tool to simplify creation and development of Ruby daemons
280
+ test_files: []