archfiend 0.1.0

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.
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: []