mooncell 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'concurrent'
4
+
5
+ module Mooncell
6
+ # The Application Configruation
7
+ #
8
+ # @since 0.1.0
9
+ # @api private
10
+ class ApplicationConfiguration
11
+ # Create new configuration
12
+ #
13
+ # @param block [Proc] the configuration block
14
+ #
15
+ # @since 0.1.0
16
+ # @api private
17
+ def initialize(&block)
18
+ @settings = {}
19
+ instance_eval(&block)
20
+ end
21
+
22
+ # Protocol
23
+ #
24
+ # @overload protocol
25
+ # Get the protocol
26
+ # @return [String] the protocol
27
+ #
28
+ # @overload protocol(value)
29
+ # Set the protocol
30
+ # @param protocol [String] the target protocol
31
+ #
32
+ # @since 0.1.0
33
+ # @api private
34
+ def protocol(value = nil)
35
+ if value
36
+ settings[:protocol] = value.to_s
37
+ else
38
+ settings[:portocol] || Mooncell.configuration.protocol
39
+ end
40
+ end
41
+
42
+ # Port
43
+ #
44
+ # @overload port
45
+ # Get the port
46
+ # @return [Number] the port
47
+ #
48
+ # @overload port(value)
49
+ # Set the port
50
+ # @param port [Number] the port
51
+ #
52
+ # @since 0.1.0
53
+ # @api private
54
+ def port(value = nil)
55
+ return settings[:port] if value.nil?
56
+
57
+ settings[:port] = value.to_i
58
+ end
59
+
60
+ private
61
+
62
+ # @since 0.1.0
63
+ # @api private
64
+ attr_reader :settings
65
+ end
66
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mooncell
4
+ # Command Line Interface
5
+ class CLI
6
+ # @since 0.1.0
7
+ # @api private
8
+ def call
9
+ command = Commands.get(ARGV)
10
+ # TODO: Display help message
11
+ return if command.nil?
12
+
13
+ command.call(ARGV)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mooncell/cli'
4
+ require 'mooncell/cli/commands/registry'
5
+ require 'mooncell/cli/commands/base'
6
+
7
+ module Mooncell
8
+ class CLI
9
+ # CLI Commands
10
+ #
11
+ # @since 0.1.0
12
+ # @api private
13
+ module Commands
14
+ # @since 0.1.0
15
+ # @api private
16
+ def self.get(arguments)
17
+ Registry.get(arguments)
18
+ end
19
+
20
+ # @return [Boolean] Is application initialized
21
+ #
22
+ # @since 0.1.0
23
+ # @api private
24
+ def self.app_initialized?
25
+ Gem.loaded_specs.key?('mooncell') &&
26
+ Mooncell.root.join('config', 'boot.rb').exist?
27
+ end
28
+
29
+ require 'mooncell/cli/commands/version'
30
+ require 'mooncell/cli/commands/console'
31
+ require 'mooncell/cli/commands/server'
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mooncell'
4
+ require 'concurrent'
5
+
6
+ module Mooncell
7
+ class CLI
8
+ module Commands
9
+ # Base class for commands
10
+ #
11
+ # @since 0.1.0
12
+ # @api private
13
+ class Base
14
+ class << self
15
+ # @since 0.1.0
16
+ # @api private
17
+ # rubocop:disable Metrics/LineLength
18
+ def register(name, command = nil, aliases: [], app_only: false, &block)
19
+ Registry.add(name, command, aliases: aliases, app_only: app_only, &block)
20
+ end
21
+ # rubocop:enable Metrics/LineLength
22
+
23
+ # @since 0.1.0
24
+ # @api private
25
+ def inherited(base)
26
+ super
27
+ base.class_eval do
28
+ @_requirements = Concurrent::Array.new
29
+ extend ClassMethods
30
+ prepend InstanceMethods
31
+ end
32
+ end
33
+ end
34
+
35
+ # @sincle 0.1.0
36
+ # @api private
37
+ module ClassMethods
38
+ # @since 0.1.0
39
+ # @api private
40
+ def requires(*names)
41
+ @_requirements.concat(names)
42
+ end
43
+
44
+ # @since 0.1.0
45
+ # @api private
46
+ def requirements
47
+ @_requirements
48
+ end
49
+ end
50
+
51
+ # @since 0.1.0
52
+ # @api private
53
+ module InstanceMethods
54
+ def call(*)
55
+ if self.class.requirements.any?
56
+ Mooncell.environment.require_project_environment
57
+ # TODO: Load requirements
58
+ Mooncell::Loader.setup
59
+ end
60
+ super
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+
5
+ module Mooncell
6
+ class CLI
7
+ module Commands
8
+ # @since 0.1.0
9
+ # @api private
10
+ class Console < Base
11
+ requires 'all'
12
+
13
+ # Provide code reload for console
14
+ #
15
+ # @since 0.1.0
16
+ # @api private
17
+ module CodeReloading
18
+ # @since 0.1.0
19
+ # @api private
20
+ def reload!
21
+ puts 'Reloading...'
22
+ Mooncell::Loader.reload!
23
+ end
24
+ end
25
+
26
+ def call(*)
27
+ TOPLEVEL_BINDING.eval('self').__send__(:include, CodeReloading)
28
+ Pry.start
29
+ end
30
+
31
+ register 'console', Commands::Console, aliases: %w[c], app_only: true
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+ require 'forwardable'
5
+
6
+ module Mooncell
7
+ class CLI
8
+ module Commands
9
+ # Command Registry
10
+ #
11
+ # @since 0.1.0
12
+ # @api private
13
+ class Registry
14
+ include Singleton
15
+
16
+ class << self
17
+ extend Forwardable
18
+
19
+ delegate %w[add get] => 'instance'
20
+ end
21
+
22
+ # @since 0.1.0
23
+ # @api private
24
+ def initialize
25
+ @root = Node.new
26
+ end
27
+
28
+ # @since 0.1.0
29
+ # @api private
30
+ def add(name, command = nil, aliases: [], app_only: false, &block)
31
+ @root.add(name, command, aliases: aliases, app_only: app_only, &block)
32
+ end
33
+
34
+ # @since 0.1.0
35
+ # @api private
36
+ def get(arguments)
37
+ node = @root
38
+
39
+ arguments.each do |token|
40
+ current = node.lookup(token)
41
+ return node if current.nil? && node.leaf?
42
+
43
+ node = current
44
+ end
45
+
46
+ node
47
+ end
48
+
49
+ # @since 0.1.0
50
+ # @api private
51
+ class Node
52
+ attr_reader :name, :command
53
+
54
+ # @since 0.1.0
55
+ # @api private
56
+ def initialize(name = nil, command = nil, app_only: false)
57
+ @name = name
58
+ @command = command
59
+ @children = {}
60
+ @app_only = app_only
61
+ end
62
+
63
+ # @return [Boolean] is only for application
64
+ #
65
+ # @since 0.1.0
66
+ # @api private
67
+ def app_only?
68
+ @app_only == true
69
+ end
70
+
71
+ # @return [Boolean] is the end of command
72
+ # @since 0.1.0
73
+ # @api private
74
+ def leaf?
75
+ @children.empty?
76
+ end
77
+
78
+ # @since 0.1.0
79
+ # @api private
80
+ def add(name, command = nil, aliases: [], app_only: false, &block)
81
+ node = Node.new(name, command || block, app_only: app_only)
82
+ @children[name] = node
83
+ aliases.each { |token| @children[token] = node }
84
+ end
85
+
86
+ # @since 0.1.0
87
+ # @api private
88
+ def lookup(name)
89
+ @children[name]
90
+ end
91
+
92
+ # @since 0.1.0
93
+ # @api private
94
+ def call(*args)
95
+ return if app_only? && !Commands.app_initialized?
96
+ return if command.nil?
97
+ return command.call(*args) if command.is_a?(Proc)
98
+
99
+ command.new.call(*args)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mooncell
4
+ class CLI
5
+ module Commands
6
+ # @since 0.1.0
7
+ # @api private
8
+ class Server < Base
9
+ requires 'all'
10
+
11
+ # @since 0.1.0
12
+ # @api private
13
+ def call(*)
14
+ # TODO: Add support for multiple application
15
+ _, app = Mooncell.configuration.apps.first
16
+ return if app.nil?
17
+
18
+ app.call
19
+ end
20
+
21
+ register 'server', Commands::Server, aliases: %w[s], app_only: true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mooncell
4
+ class CLI
5
+ module Commands
6
+ # Command to response version
7
+ #
8
+ # @since 0.1.0
9
+ # @api private
10
+ class Version < Base
11
+ # @since 0.1.0
12
+ # @api private
13
+ def call(*)
14
+ puts "v#{Mooncell::VERSION}"
15
+ end
16
+
17
+ register 'version', Commands::Version, aliases: %w[v -v --version]
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mooncell
4
+ # A Command Handler
5
+ #
6
+ # @since 0.1.0
7
+ #
8
+ # @example
9
+ # class Move
10
+ # include Mooncell::Command
11
+ #
12
+ # def call(params)
13
+ # end
14
+ # end
15
+ module Command
16
+ # @since 0.1.0
17
+ # @api private
18
+ def self.included(base)
19
+ base.class_eval do
20
+ extend ClassMethods
21
+ include InstanceMethods
22
+
23
+ attr_reader :conn
24
+ end
25
+ end
26
+
27
+ # @since 0.1.0
28
+ # @api private
29
+ module ClassMethods
30
+ # Expose instance variable
31
+ #
32
+ # @param [Array<Symbol>] the variable name to expose
33
+ #
34
+ # @since 0.1.0
35
+ # @api private
36
+ def expose(*names)
37
+ class_eval do
38
+ names.each do |name|
39
+ attr_reader name unless attr_reader?(name)
40
+ end
41
+
42
+ exposures.push(*names)
43
+ end
44
+ end
45
+
46
+ # @since 0.1.0
47
+ # @api private
48
+ def exposures
49
+ @exposures ||= []
50
+ end
51
+
52
+ private
53
+
54
+ # @since 0.1.0
55
+ # @api private
56
+ def attr_reader?(name)
57
+ (instance_methods | private_instance_methods).include?(name)
58
+ end
59
+ end
60
+
61
+ # @since 0.1.0
62
+ # @api private
63
+ module InstanceMethods
64
+ # @since 0.1.0
65
+ # @api private
66
+ def initialize(conn)
67
+ @conn = conn
68
+ end
69
+
70
+ # @since 0.1.0
71
+ # @api private
72
+ def respond
73
+ name = self.class.name.sub(/Commands/, 'Responds')
74
+ Kernel.const_get(name).new(self)
75
+ end
76
+ end
77
+ end
78
+ end