nova 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98f99f8e3d4e94b3634e3881015900048f2d1565
4
- data.tar.gz: 16f716c8f300fa1ed9d2ff472f0ca0e1ee6e97cc
3
+ metadata.gz: 11c2e75370d3f3ecf0bc62bd2f82a62f411cbdcc
4
+ data.tar.gz: a5e74b138bead7aece86bf1b769d6e79cc457732
5
5
  SHA512:
6
- metadata.gz: e53c896e97cda1f47557f7cfa670af707175f2e13bddde1dbc9e3a0ca87daaf15f85ba15bbe943a7251cbbd73a9f7e9bb519fdfadeb833665989b03241480997
7
- data.tar.gz: 4d46a1cfbc412411ffa75ed218c3cd4e907e6fdc8b63008fe7b3c78f15c0815fd7e1df5f81dcc16726c3bc9bc05f417e4f1509fc5277b16c40e190e62187b454
6
+ metadata.gz: 1d751e0be3c45d63d22c9e0169d80af621a281293715f6f483c0d002581218a2c04b46239c083b2f0ff9bcef281e7ce2b40e3ce6dea3b48f970daddac877ac47
7
+ data.tar.gz: 887e4091e028eba84f005fd8f1d446ad6814a19ee3e2674dcaeffc0fef51cb0a12de20af118644def845719345d950b142d97cbfd473150d21f198f2a8900a6e
@@ -0,0 +1 @@
1
+ gem 'nova', '~> 0.1'
@@ -1,7 +1,7 @@
1
1
  load_paths:
2
2
  - ./galaxy
3
3
 
4
- # If this is an array, every time we run +Nova server up+, multiple
4
+ # If this is an array, every time we run +nova server up+, multiple
5
5
  # instances are created, each matching the values here.
6
6
  servers:
7
7
  - :name: tcp_server
@@ -10,7 +10,7 @@ servers:
10
10
  :port: 2010
11
11
  - :name: unix_server
12
12
  :type: :unix
13
- :path: "./Nova.sock"
13
+ :path: "./nova.sock"
14
14
  :protocol:
15
15
  :allow_plaintext: true
16
16
 
@@ -23,7 +23,9 @@ module Nova
23
23
  @logger ||= Logger.new(STDOUT)
24
24
  end
25
25
 
26
- attr_writer :logger
26
+ class << self
27
+ attr_writer :logger
28
+ end
27
29
 
28
30
  # This creates a star with a given block, unless it already exists;
29
31
  # if it does, it just modifies that star.
@@ -12,7 +12,7 @@ module Nova
12
12
  :desc => "Which servers to run. Empty means all.",
13
13
  :default => []
14
14
  long_desc <<-DESC
15
- Runs servers defined in Nova.yml. If the forgeground
15
+ Runs servers defined in nova.yml. If the forgeground
16
16
  option is specified, the process is run in the foreground.
17
17
  Otherwise, it's ran as a daemon. If the which parameter is
18
18
  specified, it only runs the servers that were specified.
@@ -97,9 +97,10 @@ module Nova
97
97
  # @return [Object] the result of the event.
98
98
  def run!(name, options = {})
99
99
  matched = has_event_with_options? name, options
100
+ new_options = Metadata::Options.new(options)
100
101
 
101
102
  if matched
102
- matched.run(bind, options)
103
+ matched.run(bind, new_options)
103
104
  else
104
105
  raise NoEventError, "Could not find event #{name}."
105
106
  end
@@ -45,7 +45,7 @@ module Nova
45
45
  # @option options [Symbol] :on the platform the event
46
46
  # is written for. If this doesn't match the current
47
47
  # platform, the event is never run. Must be in the
48
- # results of {Remote::Fake::Platforms#platform} (or
48
+ # results of {Remote::Fake::Platform#types} (or
49
49
  # remote's definition of platform). Can also be +:for+.
50
50
  # @option options [Symbol, Array<Symbol>] :requires
51
51
  # what options the event requires when being run. The
@@ -1,4 +1,5 @@
1
1
  require 'nova/common/metadata/data'
2
+ require 'nova/common/metadata/options'
2
3
 
3
4
  module Nova
4
5
  module Common
@@ -43,6 +44,7 @@ module Nova
43
44
 
44
45
  # Sets the options, validating them.
45
46
  def options=(options)
47
+ options = Options.new(options)
46
48
  @meta.validate_options! options
47
49
  @options = options
48
50
  end
@@ -123,7 +123,7 @@ module Nova
123
123
  def validate_options!(options)
124
124
  keys = options.keys
125
125
 
126
- unless (data[:required_options] - keys).empty?
126
+ unless (data[:required_options].map(&:to_s) - keys).empty?
127
127
  raise InvalidOptionsError, "Missing options " +
128
128
  "#{(data[:required_options] - keys).join(', ')}"
129
129
  end
@@ -0,0 +1,71 @@
1
+ module Nova
2
+ module Common
3
+ module Metadata
4
+
5
+ # Handles options that are passed to the module.
6
+ #
7
+ # @note This stores everything in a hash, and all keys within
8
+ # hash are Strings, no matter what.
9
+ class Options < BasicObject
10
+
11
+ # Initialize the options class.
12
+ #
13
+ # @param data [Hash] the data to represent with this
14
+ # class.
15
+ def initialize(data)
16
+ @_data = data
17
+ _clean_data
18
+ end
19
+
20
+ # Accessor for this class. Returns the default value if the
21
+ # key does not exist.
22
+ #
23
+ # @param key [#to_s] the key to look up.
24
+ # @return [Object] the value.
25
+ def [](key)
26
+ fetch(key) { default(key.to_s) }
27
+ end
28
+
29
+ # Fetches the given key. If it doesn't exist, uses the given
30
+ # default value or calls the block.
31
+ #
32
+ # @param key [#to_s] the key to look up.
33
+ # @param default_value [Object] the default object to return,
34
+ # if the key doesn't exist in the table.
35
+ # @yieldparam key [String] the key that was looked up.
36
+ # @yieldreturn [Object] the value to use.
37
+ # @return [Object] the value of the key.
38
+ def fetch(key, *args, &block)
39
+ @_data.fetch(key.to_s, *args, &block)
40
+ end
41
+
42
+ # Forwards all methods to the hash.
43
+ #
44
+ # @param method [Symbol] the method to forward.
45
+ # @param arguments [Array<Object>] the arguments for the
46
+ # method.
47
+ # @return [Object]
48
+ def method_missing(method, *arguments, &block)
49
+ @_data.public_send(method, *arguments, &block)
50
+ end
51
+
52
+ private
53
+
54
+ # Cleans the data hash by forcing all keys to strings, and then
55
+ # freezes the newly created hash.
56
+ #
57
+ # @return [Hash]
58
+ def _clean_data
59
+ new_data = {}
60
+
61
+ @_data.each do |k, v|
62
+ new_data[k.to_s] = v
63
+ end
64
+
65
+ @_data = new_data.freeze
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+ end
@@ -108,6 +108,19 @@ module Nova
108
108
  super
109
109
  end
110
110
  end
111
+
112
+ # Retrieves a star from a given target. The target should be
113
+ # in the format +[<type>.]<star name>[.<action>]+.
114
+ #
115
+ # @param target [String] the target star.
116
+ # @return [nil, Class] nil if the star doesn't exist, the star
117
+ # itself otherwise.
118
+ def from_target(target)
119
+ type, star_name, action = target.scan(%r{\A(?:([\w]+)\.)?([\w]+)(?:\.([\w]+?))?\z}).first
120
+
121
+ type ||= :star
122
+ stars[type.intern][star_name.intern]
123
+ end
111
124
  end
112
125
 
113
126
  # Instance methods.
@@ -121,7 +121,7 @@ module Nova
121
121
  if File.exists?(server[:files][:pid])
122
122
  pid = File.open(server[:files][:pid], "r") { |f| f.read }.to_i
123
123
 
124
- puts "Sending INT to #{pid}..."
124
+ print "Sending INT to #{pid}... "
125
125
 
126
126
  Process.kill :INT, pid rescue Errno::ESRCH
127
127
 
@@ -187,9 +187,9 @@ module Nova
187
187
  File.delete(server[:files][:pid]) rescue Errno::ENOENT
188
188
  end
189
189
 
190
- return s.listen
190
+ s.listen
191
191
  rescue => e
192
- Nova.logger.fatal { "#{e}: #{e.message}; #{e.backtrace[0]}" }
192
+ Nova.logger.fatal { "#{e}: #{e.message} => #{e.backtrace[0]}" }
193
193
  File.delete(server[:files][:pid]) rescue Errno::ENOENT
194
194
  exit
195
195
  end
@@ -1,10 +1,17 @@
1
+
2
+
1
3
  module Nova
4
+
5
+ # Classes to handle running commands on platforms.
2
6
  module Remote
3
7
 
4
- autoload :Common, "nova/remote/common"
5
- autoload :Fake, "nova/remote/fake"
6
- autoload :Local, "nova/remote/local"
7
- autoload :SSH, "nova/remote/ssh"
8
+ if ENV["NOVA_ENV"] == "testing"
9
+ require 'nova/remote/fake'
10
+ else
11
+ autoload :Fake, "nova/remote/fake"
12
+ #autoload :Local, "nova/remote/local"
13
+ #autoload :SSH, "nova/remote/ssh"
14
+ end
8
15
 
9
16
  end
10
17
  end
@@ -0,0 +1,7 @@
1
+ module Nova
2
+ module Remote
3
+ class Local
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ require 'irb'
2
+
3
+ module Nova
4
+ class Shell
5
+
6
+ IRB_PROMPT = {
7
+ :AUTO_INDENT => true,
8
+ :PROMPT_I => "nova[%03n] >> ",
9
+ :PROMPT_S => "nova[%03n] %l> ",
10
+ :PROMPT_C => "nova[%03n] %i> ",
11
+ :RETURN => "nova <- %s\n"
12
+ }
13
+
14
+ def start_shell
15
+ IRB.setup __FILE__
16
+ IRB.conf[:PROMPT][:NOVA_PROMPT] = IRB_PROMPT
17
+ IRB.conf[:PROMPT_MODE] = :NOVA_PROMPT
18
+ irb = IRB::Irb.new(IRB::WorkSpace.new(binding))
19
+
20
+ IRB.conf[:MAIN_CONTEXT] = irb.context
21
+
22
+ trap("SIGINT") { irb.signal_handle }
23
+
24
+ begin
25
+ catch(:IRB_EXIT) { irb.eval_input }
26
+ ensure
27
+ IRB.irb_at_exit
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require "nova/starbound/default_behavior/eventable"
2
+ require "nova/starbound/default_behavior/passwordable"
3
+ require "nova/starbound/default_behavior/star_runnable"
4
+ require "nova/starbound/default_behavior/echoable"
5
+ require "multi_json"
6
+
7
+ module Nova
8
+ module Starbound
9
+ class DefaultBehavior
10
+
11
+ include Eventable
12
+ include Passwordable
13
+ include StarRunnable
14
+ include Echoable
15
+
16
+ # @!parse include Eventable::InstanceMethods
17
+ # @!parse extend Eventable::ClassMethods
18
+
19
+ # Initialize the class.
20
+ def initialize(protocol)
21
+ attach_events protocol
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ module Nova
2
+ module Starbound
3
+ class DefaultBehavior
4
+ module Echoable
5
+
6
+ # Called when this module is included into another module.
7
+ # Sets up the echo packet management.
8
+ #
9
+ # @param reciever [Module]
10
+ # @return [void]
11
+ def self.included(reciever)
12
+ reciever.handle :packet => :echo
13
+ end
14
+
15
+ private
16
+
17
+ # Handles the echo packet by responding to it with the same
18
+ # body that was sent.
19
+ #
20
+ # @return [void]
21
+ def handle_packet_echo(packet, protocol)
22
+ protocol.respond_to packet, :echo, packet.body
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,87 @@
1
+ module Nova
2
+ module Starbound
3
+ class DefaultBehavior
4
+
5
+ # Handles events such as packets.
6
+ module Eventable
7
+
8
+ # Class methods.
9
+ module ClassMethods
10
+
11
+ # Defines how to handle a specific type of packet. The
12
+ # method of handling a packet can be defined in 3 ways:
13
+ # first, if a method name (second argument) is given,
14
+ # that method is used to handle the packet. Second, if
15
+ # a block is given, that block is used. And last, if
16
+ # neither of them are provided, the method name is assumed
17
+ # from the struct type and packet type in the format
18
+ # +handle_<struct>_<packet>+. The given method can and
19
+ # should be private.
20
+ #
21
+ # @note If a block isn't used, the method should accept two
22
+ # arguments (see yield params for the arguments).
23
+ # @param type [Hash<Symbol, Symbol>] a single key-value pair,
24
+ # with the key being the struct type and the value being
25
+ # the packet type.
26
+ # @param meth [nil, Symbol] the method name to use when
27
+ # calling a block.
28
+ # @yieldparam packet [Protocol::Packet] the packet.
29
+ # @yieldparam protocol [Protocol] the protocol.
30
+ # @return [void]
31
+ def handle(type, meth = nil, &block)
32
+ struct = type.keys.first
33
+ packet = type.values.first
34
+
35
+ proc = nil
36
+
37
+ if meth
38
+ proc = meth
39
+ elsif block_given?
40
+ proc = block
41
+ else
42
+ proc = :"handle_#{struct}_#{packet}"
43
+ end
44
+
45
+ handles[{struct => packet}] = proc
46
+ end
47
+
48
+ # The handles for events that are defined on this class.
49
+ #
50
+ # @return [Hash]
51
+ def handles
52
+ @handles ||= {}
53
+ end
54
+
55
+ end
56
+
57
+ # Instance methods.
58
+ module InstanceMethods
59
+
60
+ # Attaches the specified events to the protocol.
61
+ #
62
+ # @return [void]
63
+ def attach_events(protocol)
64
+ self.class.handles.each do |k, v|
65
+ if v.is_a? Symbol
66
+ protocol.on(k, &method(v))
67
+ else
68
+ protocol.on(k, &v)
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ # Called when this module is included by a module or class.
76
+ # Extends that module or class by {ClassMethods}, and includes
77
+ # {InstanceMethods} into that class.
78
+ #
79
+ # @return [void]
80
+ def self.included(receiver)
81
+ receiver.extend ClassMethods
82
+ receiver.send :include, InstanceMethods
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,75 @@
1
+ module Nova
2
+ module Starbound
3
+ class DefaultBehavior
4
+
5
+ # Handles passwords with the default behavior.
6
+ module Passwordable
7
+
8
+ # The current password. If it's nil, any password works; if
9
+ # it's an empty string, no password works; and if it's a
10
+ # string, only passwords matching that string works.
11
+ #
12
+ # @return [nil, String]
13
+ attr_writer :password
14
+
15
+ # Checks to see if the given password is valid. Returns
16
+ # false if it isn't, true if it is.
17
+ #
18
+ # @param pass [String] the password to check.
19
+ # @return [Boolean]
20
+ def valid_password?(pass)
21
+ if password.nil? || (pass == password && password != "")
22
+ true
23
+ else
24
+ false
25
+ end
26
+ end
27
+
28
+ # Checks to see if the given password is valid. If it is, it
29
+ # sets authenticated to true. Otherwise, sets it to false.
30
+ #
31
+ # @param pass [String] the password to check.
32
+ # @return [Boolean]
33
+ def check_password(pass)
34
+ @authenticated = valid_password? pass
35
+ end
36
+
37
+ # Whether or not it was authenticated.
38
+ #
39
+ # @return [Boolean]
40
+ def authenticated?
41
+ @authenticated
42
+ end
43
+
44
+ private
45
+
46
+ # Handles the password packet, by checking the password. If it
47
+ # matches, it returns an "OK" packet. Otherwise, it returns a
48
+ # "FAIL" packet.
49
+ #
50
+ # @param packet [Protocol::Packet] the packet that the client sent.
51
+ # @param proto [Protocol] the protocol used to communicate
52
+ # with the client.
53
+ # @return [void]
54
+ def handle_packet_password(packet, proto)
55
+ if reciever.check_password packet.body
56
+ proto.respond_to packet, :password, "OK"
57
+ else
58
+ proto.respond_to packet, :password, "FAIL"
59
+ end
60
+ end
61
+
62
+ public
63
+
64
+ # When this is included by {DefaultBehavior}, define the
65
+ # packets nessicary for password management.
66
+ #
67
+ # @return [void]
68
+ def self.included(reciever)
69
+ reciever.handle :packet => :password
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,61 @@
1
+ module Nova
2
+ module Starbound
3
+ class DefaultBehavior
4
+
5
+ # Handles running stars.
6
+ module StarRunnable
7
+
8
+ # Runs the star with the given information.
9
+ #
10
+ # @param target [String] the target to originate the star to
11
+ # run from.
12
+ # @param data [Hash] the data to pass to the event.
13
+ # @return [Boolean] if it was successful.
14
+ def run_star(target, data)
15
+ return false unless authenticated?
16
+ star = Star.from_target target
17
+
18
+ return false unless star
19
+ inst = star.new Remote::Local
20
+ inst.options = data["options"]
21
+ out = inst.run(target.split('.').last, data["arguments"])
22
+
23
+ if out.is_a? NoEventError
24
+ return false
25
+ else
26
+ return true
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ # Handles an incoming packet request for handling stars.
33
+ #
34
+ # @param packet [Protocol::Packet] the packet to handle.
35
+ # @param protocol [Protocol] the protocol.
36
+ # @return [void]
37
+ def handle_packet_star_run(packet, protocol)
38
+ raw = MultiJson.load packet.body
39
+
40
+ if raw["target"] && run_star(raw["target"], raw)
41
+ else
42
+ protocol.respond_to packet, :standard_error, "Unable to run #{raw["target"]}"
43
+ end
44
+
45
+ rescue MultiJson::LoadError => e
46
+ protocol.respond_to packet, :standard_error, e.message
47
+ end
48
+
49
+ public
50
+
51
+ # When this is included by {DefaultBehavior}, define the
52
+ # packets nessicary for star running.
53
+ #
54
+ # @return [void]
55
+ def self.included(reciever)
56
+ reciever.handle :packet => :star_run
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -3,6 +3,7 @@ require 'nova/starbound/protocol/encryption'
3
3
  require 'nova/starbound/protocol/messages'
4
4
  require 'nova/starbound/protocol/packet'
5
5
  require 'nova/starbound/protocol/socket'
6
+ require 'nova/starbound/default_behavior'
6
7
 
7
8
  module Nova
8
9
  module Starbound
@@ -76,6 +77,13 @@ module Nova
76
77
  @state = :offline
77
78
  end
78
79
 
80
+ # Sets up default behaviors within this protocol.
81
+ #
82
+ # @return [DefaultBehavior]
83
+ def default_behavior
84
+ @_default_behavior ||= DefaultBehavior.new(self)
85
+ end
86
+
79
87
  end
80
88
  end
81
89
  end
@@ -49,7 +49,9 @@ module Nova
49
49
  :close => 0x05,
50
50
 
51
51
  # content
52
- :echo => 0x06
52
+ :echo => 0x06,
53
+ :password => 0x07,
54
+ :star_run => 0x08
53
55
  }.freeze
54
56
 
55
57
  # Used internally to check the types of packets when
@@ -150,7 +150,7 @@ module Nova
150
150
  @_callbacks ||= Hash.new { |h, k| h[k] = [] }
151
151
  end
152
152
 
153
- # Runs a callback.
153
+ # Runs a callback. Automatically called by #wait_for_socket.
154
154
  #
155
155
  # @param struct [Symbol] the struct that the callback is for.
156
156
  # @param type [Symbol] the type of callback this is for.
@@ -219,7 +219,8 @@ module Nova
219
219
  packet = encryption_provider.decrypt(
220
220
  Packet.from_socket(socket))
221
221
 
222
- run_callback packet.struct, packet.type, packet
222
+ run_callback packet.struct, packet.type,
223
+ packet, self unless state == :handshake
223
224
  end
224
225
 
225
226
  packet
@@ -1,5 +1,5 @@
1
1
  module Nova
2
2
 
3
3
  # The version of Nova.
4
- VERSION = "0.0.2".freeze
4
+ VERSION = "0.0.3".freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nova
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-19 00:00:00.000000000 Z
11
+ date: 2013-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: command-runner
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.18'
69
+ - !ruby/object:Gem::Dependency
70
+ name: multi_json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -95,8 +109,10 @@ files:
95
109
  - lib/nova/remote/fake/commands.rb
96
110
  - lib/nova/remote/fake/file_system.rb
97
111
  - lib/nova/remote/fake.rb
112
+ - lib/nova/remote/local.rb
98
113
  - lib/nova/project.rb
99
114
  - lib/nova/common/metadata/data.rb
115
+ - lib/nova/common/metadata/options.rb
100
116
  - lib/nova/common/features.rb
101
117
  - lib/nova/common/features/feature.rb
102
118
  - lib/nova/common/metadata.rb
@@ -104,6 +120,7 @@ files:
104
120
  - lib/nova/common/event_handler.rb
105
121
  - lib/nova/common/star_management.rb
106
122
  - lib/nova/version.rb
123
+ - lib/nova/shell.rb
107
124
  - lib/nova/remote.rb
108
125
  - lib/nova/common.rb
109
126
  - lib/nova/star.rb
@@ -119,13 +136,19 @@ files:
119
136
  - lib/nova/starbound/protocol/encryption.rb
120
137
  - lib/nova/starbound/protocol/packet.rb
121
138
  - lib/nova/starbound/protocol/exceptions.rb
139
+ - lib/nova/starbound/default_behavior/eventable.rb
140
+ - lib/nova/starbound/default_behavior/passwordable.rb
141
+ - lib/nova/starbound/default_behavior/echoable.rb
142
+ - lib/nova/starbound/default_behavior/star_runnable.rb
122
143
  - lib/nova/starbound/encryptor.rb
123
144
  - lib/nova/starbound/protocol.rb
145
+ - lib/nova/starbound/default_behavior.rb
124
146
  - lib/nova/exceptions.rb
125
147
  - lib/nova/constructor.rb
126
148
  - lib/nova/starbound.rb
127
- - lib/generator/template/new_install/supernova.yml
128
149
  - lib/generator/template/new_install/galaxy/some_star.rb
150
+ - lib/generator/template/new_install/Gemfile
151
+ - lib/generator/template/new_install/nova.yml
129
152
  - lib/nova.rb
130
153
  - bin/nova
131
154
  - spec/constructor_spec.rb
@@ -141,7 +164,8 @@ files:
141
164
  - spec/starbound/rbnacl_encryptor_spec.rb
142
165
  - spec/star_spec.rb
143
166
  homepage: http://redjazz96.github.io/nova/
144
- licenses: []
167
+ licenses:
168
+ - MIT
145
169
  metadata: {}
146
170
  post_install_message:
147
171
  rdoc_options: []
@@ -164,3 +188,4 @@ signing_key:
164
188
  specification_version: 4
165
189
  summary: Software management system. Boom.
166
190
  test_files: []
191
+ has_rdoc: false