darksky-ruby 0.0.2 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 62a900ed0c6248ca0f923c8d21d9313d91710420
4
- data.tar.gz: 87a437d159fca922f16601a92dbb947e841e93b7
2
+ SHA256:
3
+ metadata.gz: cbc838749139b38df86429dd389d8758c5202fd9c77cf4ee7c8c3dc195e79ab3
4
+ data.tar.gz: 0ef99dc1e4d4d3dccf3b206118da701b2655a89e05576fee1f6ddd3e366cf809
5
5
  SHA512:
6
- metadata.gz: 6b2b0f2b5e01e70b14512cafe490a317e8c18550aa13a996a27ef8f327a4d08eace4a8616d65d206128e55c4fe013665ffd132ff8d52b941161a28f6405a352b
7
- data.tar.gz: 91fe232ff29d2d4e3fe70e6e08c90a64aa20b0ce07ffecc4d548783616befe65652d3e036cd9b873e60638b10b69eebe0e065bee9575174b6b019e56ea6b1f45
6
+ metadata.gz: 18eb161d289183c5b59dcef356665988db7e2f34d1d6a77d32a74f951b565f1960a5c65e6e95a9480b57622452a9fea8b2d1cdabbc8b34eb5eab6ad7518915fc
7
+ data.tar.gz: 2e7f16e29f5e1f566a55cabfb2fb58652cf02f66b4960eb9858b97efe76fe860c7d4fd1d0563f4d844ec14518de3b2be99640100197dc7c09b59b8f34925fb09
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Ken J.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # darksky-ruby
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/kajiki.svg)](http://badge.fury.io/rb/kajiki)
4
+
5
+ Pure simple Ruby based [Dark Sky API](https://darksky.net/dev/) gem
6
+
7
+ ## Install
8
+
9
+ ```
10
+ $ gem install darksky-ruby
11
+ ```
12
+
13
+ ## Use
14
+
15
+ ### [Forecast Request](https://darksky.net/dev/docs#forecast-request)
16
+
17
+ Example of querying weather forecast for [SFO](https://www.airport-sfo.com/).
18
+
19
+ ```ruby
20
+ require 'darksky-ruby'
21
+
22
+ api = DarkSkyAPI.new(key: 'Your_Dark_Sky_API_Secret_Key')
23
+ data = api.forecast(lat: 37.6211, lon: -122.383)
24
+ p data[:hourly][:summary]
25
+ # => "Partly cloudy throughout the day."
26
+ ```
27
+
28
+ ### [Time Machine Request](https://darksky.net/dev/docs#time-machine-request)
29
+
30
+ Requesting observed weather for noon of Jan. 1, 2018 at SFO.
31
+
32
+ ```ruby
33
+ data = api.timemachine(lat: 37.6211, lon: -122.383, ts: Time.new(2018,1,1,12))
34
+ p data[:currently][:temperature]
35
+ # => 57.56
36
+ ```
37
+
38
+ ### [Response Format](https://darksky.net/dev/docs#response-format)
39
+
40
+ `data` in above examples would contain a Ruby Hash of the entire API response; all keys are symbolized.
41
+
42
+ ### Options
43
+
44
+ You can limit the response data size by excluding unnecessary blocks.
45
+
46
+ ```ruby
47
+ api.blocks = {minutely: false, hourly: false} # excludes blocks marked false
48
+ api.include_only([:currently, :alerts]) # excludes everything except specified
49
+ api.blocks
50
+ # => {:currently=>true, :minutely=>false, :hourly=>false, :daily=>false,
51
+ # :alerts=>true, :flags=>false}
52
+ ```
53
+
54
+ Hint, you can use `api.blocks` first to get a default Hash to get started. After you've modified the Hash, you can save it with `api.blocks =`.
55
+
56
+ Other options can be set like so.
57
+
58
+ ```ruby
59
+ api.options = {lang: 'es', units: 'si'} # Spanish language, SI units
60
+ data = api.timemachine(lat: 37.6211, lon: -122.383, ts: Time.new(2018,1,1,12))
61
+ p data[:currently][:summary]
62
+ # => "Parcialmente Nublado"
63
+ p data[:currently][:temperature]
64
+ # => 14.2
65
+ ```
66
+
67
+ ## CLI
68
+
69
+ This gem includes an executable as an example.
70
+
71
+ ```
72
+ $ darksky -h
73
+ darksky [options] <LAT,LON>
74
+ -k, --key=<s> API secret key
75
+ -l, --loc=<s> Location (latitude,longtitude)
76
+ -o, --log=<s> Log file
77
+ -t, --time=<s> Timestamp for Time Machine request
78
+ -v, --verbose Verbose mode
79
+ -h, --help Show this message
80
+ ```
81
+
82
+ ## More
83
+
84
+ Since this is a simple gem with no external dependencies, you can directly include the `lib` contents in your project if you prefer not to use Ruby Gems, such as in [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/ruby-package.html). If you do, be sure to include my copyright and license details.
data/bin/darksky CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
- require 'darksky-ruby/trollop'
2
+ require 'darksky-ruby/optimist'
3
3
  require 'darksky-ruby'
4
4
 
5
5
 
6
- opts = Trollop::options do
6
+ opts = Optimist::options do
7
7
  banner "darksky [options] <LAT,LON>"
8
8
  opt :key, 'API secret key', type: :string
9
9
  opt :loc, 'Location (latitude,longtitude)', type: :string
@@ -28,9 +28,9 @@ log.debug("Command line arguments: #{opts}")
28
28
  loc = opts[:loc]
29
29
  loc ||= ARGV.shift
30
30
 
31
- Trollop::die :loc, "is missing" if loc.nil?
31
+ Optimist::die :loc, "is missing" if loc.nil?
32
32
 
33
- api = DarkskyAPI.new(key: opts[:key])
33
+ api = DarkSkyAPI.new(key: opts[:key])
34
34
  api.blocks = {minutely: false, hourly: false, daily: false, alerts: false, flags: false}
35
35
 
36
36
  if opts[:time_given]
data/darksky-ruby.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
- require 'darksky-ruby/version'
2
+ require 'darksky-ruby'
3
3
 
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'darksky-ruby'
7
- s.version = Darksky::Version
7
+ s.version = '1.0.0'
8
8
  s.authors = ['Ken J.']
9
9
  s.email = ['kenjij@gmail.com']
10
- s.summary = %q{Pure simple Ruby based Darksky REST library}
11
- s.description = %q{Darksky library written in pure Ruby without external dependency.}
10
+ s.summary = %q{Pure simple Ruby based Dark Sky API gem}
11
+ s.description = %q{Dark Sky gem written in pure Ruby without any external dependency.}
12
12
  s.homepage = 'https://github.com/kenjij/darksky-ruby'
13
13
  s.license = 'MIT'
14
14
 
@@ -1,6 +1,6 @@
1
1
  require 'json'
2
2
 
3
- class DarkskyAPI
3
+ class DarkSkyAPI
4
4
  DARKSKY_URL = 'https://api.darksky.net/'
5
5
  DARKSKY_PATH_TEMPLATE = '/forecast/%{key}/%{loc}'
6
6
  DARKSKY_BLOCK_NAMES = [:currently, :minutely, :hourly, :daily, :alerts, :flags]
@@ -1,17 +1,17 @@
1
- # lib/trollop.rb -- trollop command-line processing library
1
+ # lib/optimist.rb -- optimist command-line processing library
2
2
  # Copyright (c) 2008-2014 William Morgan.
3
3
  # Copyright (c) 2014 Red Hat, Inc.
4
- # trollop is licensed under the MIT license.
4
+ # optimist is licensed under the MIT license.
5
5
 
6
6
  require 'date'
7
7
 
8
- module Trollop
8
+ module Optimist
9
9
  # note: this is duplicated in gemspec
10
10
  # please change over there too
11
- VERSION = "2.1.2"
11
+ VERSION = "3.0.0"
12
12
 
13
13
  ## Thrown by Parser in the event of a commandline error. Not needed if
14
- ## you're using the Trollop::options entry.
14
+ ## you're using the Optimist::options entry.
15
15
  class CommandlineError < StandardError
16
16
  attr_reader :error_code
17
17
 
@@ -22,12 +22,12 @@ class CommandlineError < StandardError
22
22
  end
23
23
 
24
24
  ## Thrown by Parser if the user passes in '-h' or '--help'. Handled
25
- ## automatically by Trollop#options.
25
+ ## automatically by Optimist#options.
26
26
  class HelpNeeded < StandardError
27
27
  end
28
28
 
29
29
  ## Thrown by Parser if the user passes in '-v' or '--version'. Handled
30
- ## automatically by Trollop#options.
30
+ ## automatically by Optimist#options.
31
31
  class VersionNeeded < StandardError
32
32
  end
33
33
 
@@ -38,15 +38,38 @@ FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)?$/
38
38
  PARAM_RE = /^-(-|\.$|[^\d\.])/
39
39
 
40
40
  ## The commandline parser. In typical usage, the methods in this class
41
- ## will be handled internally by Trollop::options. In this case, only the
41
+ ## will be handled internally by Optimist::options. In this case, only the
42
42
  ## #opt, #banner and #version, #depends, and #conflicts methods will
43
43
  ## typically be called.
44
44
  ##
45
45
  ## If you want to instantiate this class yourself (for more complicated
46
46
  ## argument-parsing logic), call #parse to actually produce the output hash,
47
47
  ## and consider calling it from within
48
- ## Trollop::with_standard_exception_handling.
48
+ ## Optimist::with_standard_exception_handling.
49
49
  class Parser
50
+
51
+ ## The registry is a class-instance-variable map of option aliases to their subclassed Option class.
52
+ @registry = {}
53
+
54
+ ## The Option subclasses are responsible for registering themselves using this function.
55
+ def self.register(lookup, klass)
56
+ @registry[lookup.to_sym] = klass
57
+ end
58
+
59
+ ## Gets the class from the registry.
60
+ ## Can be given either a class-name, e.g. Integer, a string, e.g "integer", or a symbol, e.g :integer
61
+ def self.registry_getopttype(type)
62
+ return nil unless type
63
+ if type.respond_to?(:name)
64
+ type = type.name
65
+ lookup = type.downcase.to_sym
66
+ else
67
+ lookup = type.to_sym
68
+ end
69
+ raise ArgumentError, "Unsupported argument type '#{type}', registry lookup '#{lookup}'" unless @registry.has_key?(lookup)
70
+ return @registry[lookup].new
71
+ end
72
+
50
73
  INVALID_SHORT_ARG_REGEX = /[\d-]/ #:nodoc:
51
74
 
52
75
  ## The values from the commandline that were not interpreted by #parse.
@@ -75,7 +98,7 @@ class Parser
75
98
  @educate_on_error = false
76
99
  @synopsis = nil
77
100
  @usage = nil
78
-
101
+
79
102
  # instance_eval(&b) if b # can't take arguments
80
103
  cloaker(&b).bind(self).call(*a) if b
81
104
  end
@@ -90,7 +113,7 @@ class Parser
90
113
  ## [+:long+] Specify the long form of the argument, i.e. the form with two dashes. If unspecified, will be automatically derived based on the argument name by turning the +name+ option into a string, and replacing any _'s by -'s.
91
114
  ## [+:short+] Specify the short form of the argument, i.e. the form with one dash. If unspecified, will be automatically derived from +name+. Use :none: to not have a short value.
92
115
  ## [+:type+] Require that the argument take a parameter or parameters of type +type+. For a single parameter, the value can be a member of +SINGLE_ARG_TYPES+, or a corresponding Ruby class (e.g. +Integer+ for +:int+). For multiple-argument parameters, the value can be any member of +MULTI_ARG_TYPES+ constant. If unset, the default argument type is +:flag+, meaning that the argument does not take a parameter. The specification of +:type+ is not necessary if a +:default+ is given.
93
- ## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Trollop::options) will have a +nil+ value for this key unless the argument is given on the commandline. The argument type is derived automatically from the class of the default value given, so specifying a +:type+ is not necessary if a +:default+ is given. (But see below for an important caveat when +:multi+: is specified too.) If the argument is a flag, and the default is set to +true+, then if it is specified on the the commandline the value will be +false+.
116
+ ## [+:default+] Set the default value for an argument. Without a default value, the hash returned by #parse (and thus Optimist::options) will have a +nil+ value for this key unless the argument is given on the commandline. The argument type is derived automatically from the class of the default value given, so specifying a +:type+ is not necessary if a +:default+ is given. (But see below for an important caveat when +:multi+: is specified too.) If the argument is a flag, and the default is set to +true+, then if it is specified on the the commandline the value will be +false+.
94
117
  ## [+:required+] If set to +true+, the argument must be provided on the commandline.
95
118
  ## [+:multi+] If set to +true+, allows multiple occurrences of the option on the commandline. Otherwise, only a single instance of the option is allowed. (Note that this is different from taking multiple parameters. See below.)
96
119
  ##
@@ -116,7 +139,7 @@ class Parser
116
139
  ## There's one ambiguous case to be aware of: when +:multi+: is true and a
117
140
  ## +:default+ is set to an array (of something), it's ambiguous whether this
118
141
  ## is a multi-value argument as well as a multi-occurrence argument.
119
- ## In thise case, Trollop assumes that it's not a multi-value argument.
142
+ ## In thise case, Optimist assumes that it's not a multi-value argument.
120
143
  ## If you want a multi-value, multi-occurrence argument with a default
121
144
  ## value, you must specify +:type+ as well.
122
145
 
@@ -164,7 +187,7 @@ class Parser
164
187
 
165
188
  ## Marks two (or more!) options as requiring each other. Only handles
166
189
  ## undirected (i.e., mutual) dependencies. Directed dependencies are
167
- ## better modeled with Trollop::die.
190
+ ## better modeled with Optimist::die.
168
191
  def depends(*syms)
169
192
  syms.each { |sym| raise ArgumentError, "unknown option '#{sym}'" unless @specs[sym] }
170
193
  @constraints << [:depends, syms]
@@ -182,7 +205,7 @@ class Parser
182
205
  ## intact.
183
206
  ##
184
207
  ## A typical use case would be for subcommand support, where these
185
- ## would be set to the list of subcommands. A subsequent Trollop
208
+ ## would be set to the list of subcommands. A subsequent Optimist
186
209
  ## invocation would then be used to parse subcommand options, after
187
210
  ## shifting the subcommand off of ARGV.
188
211
  def stop_on(*words)
@@ -203,7 +226,7 @@ class Parser
203
226
  @educate_on_error = true
204
227
  end
205
228
 
206
- ## Parses the commandline. Typically called by Trollop::options,
229
+ ## Parses the commandline. Typically called by Optimist::options,
207
230
  ## but you can call it directly if you need more control.
208
231
  ##
209
232
  ## throws CommandlineError, HelpNeeded, and VersionNeeded exceptions.
@@ -240,7 +263,7 @@ class Parser
240
263
 
241
264
  sym = nil if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
242
265
 
243
- next 0 if ignore_invalid_options && !sym
266
+ next nil if ignore_invalid_options && !sym
244
267
  raise CommandlineError, "unknown argument '#{arg}'" unless sym
245
268
 
246
269
  if given_args.include?(sym) && !@specs[sym].multi?
@@ -255,7 +278,7 @@ class Parser
255
278
  # The block returns the number of parameters taken.
256
279
  num_params_taken = 0
257
280
 
258
- unless params.nil?
281
+ unless params.empty?
259
282
  if @specs[sym].single_arg?
260
283
  given_args[sym][:params] << params[0, 1] # take the first parameter
261
284
  num_params_taken = 1
@@ -301,20 +324,7 @@ class Parser
301
324
 
302
325
  vals["#{sym}_given".intern] = true # mark argument as specified on the commandline
303
326
 
304
- case opts.type
305
- when :flag
306
- vals[sym] = (sym.to_s =~ /^no_/ ? negative_given : !negative_given)
307
- when :int, :ints
308
- vals[sym] = params.map { |pg| pg.map { |p| parse_integer_parameter p, arg } }
309
- when :float, :floats
310
- vals[sym] = params.map { |pg| pg.map { |p| parse_float_parameter p, arg } }
311
- when :string, :strings
312
- vals[sym] = params.map { |pg| pg.map(&:to_s) }
313
- when :io, :ios
314
- vals[sym] = params.map { |pg| pg.map { |p| parse_io_parameter p, arg } }
315
- when :date, :dates
316
- vals[sym] = params.map { |pg| pg.map { |p| parse_date_parameter p, arg } }
317
- end
327
+ vals[sym] = opts.parse(params, negative_given)
318
328
 
319
329
  if opts.single_arg?
320
330
  if opts.multi? # multiple options, each with a single parameter
@@ -344,41 +354,13 @@ class Parser
344
354
  vals
345
355
  end
346
356
 
347
- def parse_date_parameter(param, arg) #:nodoc:
348
- begin
349
- require 'chronic'
350
- time = Chronic.parse(param)
351
- rescue LoadError
352
- # chronic is not available
353
- end
354
- time ? Date.new(time.year, time.month, time.day) : Date.parse(param)
355
- rescue ArgumentError
356
- raise CommandlineError, "option '#{arg}' needs a date"
357
- end
358
-
359
357
  ## Print the help message to +stream+.
360
358
  def educate(stream = $stdout)
361
359
  width # hack: calculate it now; otherwise we have to be careful not to
362
360
  # call this unless the cursor's at the beginning of a line.
361
+
363
362
  left = {}
364
- @specs.each do |name, spec|
365
- left[name] =
366
- (spec.short? ? "-#{spec.short}, " : "") + "--#{spec.long}" +
367
- case spec.type
368
- when :flag then ""
369
- when :int then "=<i>"
370
- when :ints then "=<i+>"
371
- when :string then "=<s>"
372
- when :strings then "=<s+>"
373
- when :float then "=<f>"
374
- when :floats then "=<f+>"
375
- when :io then "=<filename/uri>"
376
- when :ios then "=<filename/uri+>"
377
- when :date then "=<date>"
378
- when :dates then "=<date+>"
379
- end +
380
- (spec.flag? && spec.default ? ", --no-#{spec.long}" : "")
381
- end
363
+ @specs.each { |name, spec| left[name] = spec.educate }
382
364
 
383
365
  leftcol_width = left.values.map(&:length).max || 0
384
366
  rightcol_start = leftcol_width + 6 # spaces
@@ -400,27 +382,8 @@ class Parser
400
382
 
401
383
  spec = @specs[opt]
402
384
  stream.printf " %-#{leftcol_width}s ", left[opt]
403
- desc = spec.desc + begin
404
- default_s = case spec.default
405
- when $stdout then "<stdout>"
406
- when $stdin then "<stdin>"
407
- when $stderr then "<stderr>"
408
- when Array
409
- spec.default.join(", ")
410
- else
411
- spec.default.to_s
412
- end
385
+ desc = spec.description_with_default
413
386
 
414
- if spec.default
415
- if spec.desc =~ /\.$/
416
- " (Default: #{default_s})"
417
- else
418
- " (default: #{default_s})"
419
- end
420
- else
421
- ""
422
- end
423
- end
424
387
  stream.puts wrap(desc, :width => width - rightcol_start - 1, :prefix => rightcol_start)
425
388
  end
426
389
  end
@@ -460,8 +423,9 @@ class Parser
460
423
  end
461
424
  end
462
425
 
463
- ## The per-parser version of Trollop::die (see that for documentation).
426
+ ## The per-parser version of Optimist::die (see that for documentation).
464
427
  def die(arg, msg = nil, error_code = nil)
428
+ msg, error_code = nil, msg if msg.kind_of?(Integer)
465
429
  if msg
466
430
  $stderr.puts "Error: argument --#{@specs[arg].long} #{msg}."
467
431
  else
@@ -489,47 +453,60 @@ private
489
453
  when /^--$/ # arg terminator
490
454
  return remains += args[(i + 1)..-1]
491
455
  when /^--(\S+?)=(.*)$/ # long argument with equals
492
- yield "--#{$1}", [$2]
456
+ num_params_taken = yield "--#{$1}", [$2]
457
+ if num_params_taken.nil?
458
+ remains << args[i]
459
+ if @stop_on_unknown
460
+ return remains += args[i + 1..-1]
461
+ end
462
+ end
493
463
  i += 1
494
464
  when /^--(\S+)$/ # long argument
495
465
  params = collect_argument_parameters(args, i + 1)
496
- if params.empty?
497
- yield args[i], nil
498
- i += 1
499
- else
500
- num_params_taken = yield args[i], params
501
- unless num_params_taken
502
- if @stop_on_unknown
503
- return remains += args[i + 1..-1]
504
- else
505
- remains += params
506
- end
466
+ num_params_taken = yield args[i], params
467
+
468
+ if num_params_taken.nil?
469
+ remains << args[i]
470
+ if @stop_on_unknown
471
+ return remains += args[i + 1..-1]
507
472
  end
508
- i += 1 + num_params_taken
473
+ else
474
+ i += num_params_taken
509
475
  end
476
+ i += 1
510
477
  when /^-(\S+)$/ # one or more short arguments
478
+ short_remaining = ""
511
479
  shortargs = $1.split(//)
512
480
  shortargs.each_with_index do |a, j|
513
481
  if j == (shortargs.length - 1)
514
482
  params = collect_argument_parameters(args, i + 1)
515
- if params.empty?
516
- yield "-#{a}", nil
517
- i += 1
518
- else
519
- num_params_taken = yield "-#{a}", params
520
- unless num_params_taken
521
- if @stop_on_unknown
522
- return remains += args[i + 1..-1]
523
- else
524
- remains += params
525
- end
483
+
484
+ num_params_taken = yield "-#{a}", params
485
+ unless num_params_taken
486
+ short_remaining << a
487
+ if @stop_on_unknown
488
+ remains << "-#{short_remaining}"
489
+ return remains += args[i + 1..-1]
526
490
  end
527
- i += 1 + num_params_taken
491
+ else
492
+ i += num_params_taken
528
493
  end
529
494
  else
530
- yield "-#{a}", nil
495
+ unless yield "-#{a}", []
496
+ short_remaining << a
497
+ if @stop_on_unknown
498
+ short_remaining += shortargs[j + 1..-1].join
499
+ remains << "-#{short_remaining}"
500
+ return remains += args[i + 1..-1]
501
+ end
502
+ end
531
503
  end
532
504
  end
505
+
506
+ unless short_remaining.empty?
507
+ remains << "-#{short_remaining}"
508
+ end
509
+ i += 1
533
510
  else
534
511
  if @stop_on_unknown
535
512
  return remains += args[i..-1]
@@ -543,29 +520,6 @@ private
543
520
  remains
544
521
  end
545
522
 
546
- def parse_integer_parameter(param, arg)
547
- raise CommandlineError, "option '#{arg}' needs an integer" unless param =~ /^-?[\d_]+$/
548
- param.to_i
549
- end
550
-
551
- def parse_float_parameter(param, arg)
552
- raise CommandlineError, "option '#{arg}' needs a floating-point number" unless param =~ FLOAT_RE
553
- param.to_f
554
- end
555
-
556
- def parse_io_parameter(param, arg)
557
- if param =~ /^(stdin|-)$/i
558
- $stdin
559
- else
560
- require 'open-uri'
561
- begin
562
- open param
563
- rescue SystemCallError => e
564
- raise CommandlineError, "file or url for option '#{arg}' cannot be opened: #{e.message}"
565
- end
566
- end
567
- end
568
-
569
523
  def collect_argument_parameters(args, start_at)
570
524
  params = []
571
525
  pos = start_at
@@ -621,173 +575,318 @@ private
621
575
  end
622
576
  end
623
577
 
624
- ## The option for each flag
625
578
  class Option
626
- ## The set of values that indicate a flag option when passed as the
627
- ## +:type+ parameter of #opt.
628
- FLAG_TYPES = [:flag, :bool, :boolean]
629
579
 
630
- ## The set of values that indicate a single-parameter (normal) option when
631
- ## passed as the +:type+ parameter of #opt.
632
- ##
633
- ## A value of +io+ corresponds to a readable IO resource, including
634
- ## a filename, URI, or the strings 'stdin' or '-'.
635
- SINGLE_ARG_TYPES = [:int, :integer, :string, :double, :float, :io, :date]
636
-
637
- ## The set of values that indicate a multiple-parameter option (i.e., that
638
- ## takes multiple space-separated values on the commandline) when passed as
639
- ## the +:type+ parameter of #opt.
640
- MULTI_ARG_TYPES = [:ints, :integers, :strings, :doubles, :floats, :ios, :dates]
641
-
642
- ## The complete set of legal values for the +:type+ parameter of #opt.
643
- TYPES = FLAG_TYPES + SINGLE_ARG_TYPES + MULTI_ARG_TYPES
644
-
645
- attr_accessor :name, :opts
646
-
647
- def initialize(name, desc="", opts={}, &b)
648
- ## fill in :type
649
- opts[:type] = # normalize
650
- case opts[:type]
651
- when :boolean, :bool then :flag
652
- when :integer then :int
653
- when :integers then :ints
654
- when :double then :float
655
- when :doubles then :floats
656
- when Class
657
- case opts[:type].name
658
- when 'TrueClass',
659
- 'FalseClass' then :flag
660
- when 'String' then :string
661
- when 'Integer' then :int
662
- when 'Float' then :float
663
- when 'IO' then :io
664
- when 'Date' then :date
665
- else
666
- raise ArgumentError, "unsupported argument type '#{opts[:type].class.name}'"
667
- end
668
- when nil then nil
669
- else
670
- raise ArgumentError, "unsupported argument type '#{opts[:type]}'" unless TYPES.include?(opts[:type])
671
- opts[:type]
672
- end
580
+ attr_accessor :name, :short, :long, :default
581
+ attr_writer :multi_given
673
582
 
674
- ## for options with :multi => true, an array default doesn't imply
675
- ## a multi-valued argument. for that you have to specify a :type
676
- ## as well. (this is how we disambiguate an ambiguous situation;
677
- ## see the docs for Parser#opt for details.)
678
- disambiguated_default = if opts[:multi] && opts[:default].kind_of?(Array) && !opts[:type]
679
- opts[:default].first
680
- else
681
- opts[:default]
583
+ def initialize
584
+ @long = nil
585
+ @short = nil
586
+ @name = nil
587
+ @multi_given = false
588
+ @hidden = false
589
+ @default = nil
590
+ @optshash = Hash.new()
591
+ end
592
+
593
+ def opts(key)
594
+ @optshash[key]
595
+ end
596
+
597
+ def opts=(o)
598
+ @optshash = o
599
+ end
600
+
601
+ ## Indicates a flag option, which is an option without an argument
602
+ def flag? ; false ; end
603
+ def single_arg?
604
+ !self.multi_arg? && !self.flag?
605
+ end
606
+
607
+ def multi ; @multi_given ; end
608
+ alias multi? multi
609
+
610
+ ## Indicates that this is a multivalued (Array type) argument
611
+ def multi_arg? ; false ; end
612
+ ## note: Option-Types with both multi_arg? and flag? false are single-parameter (normal) options.
613
+
614
+ def array_default? ; self.default.kind_of?(Array) ; end
615
+
616
+ def short? ; short && short != :none ; end
617
+
618
+ def callback ; opts(:callback) ; end
619
+ def desc ; opts(:desc) ; end
620
+
621
+ def required? ; opts(:required) ; end
622
+
623
+ def parse(_paramlist, _neg_given)
624
+ raise NotImplementedError, "parse must be overridden for newly registered type"
625
+ end
626
+
627
+ # provide type-format string. default to empty, but user should probably override it
628
+ def type_format ; "" ; end
629
+
630
+ def educate
631
+ (short? ? "-#{short}, " : "") + "--#{long}" + type_format + (flag? && default ? ", --no-#{long}" : "")
632
+ end
633
+
634
+ ## Format the educate-line description including the default-value(s)
635
+ def description_with_default
636
+ return desc unless default
637
+ default_s = case default
638
+ when $stdout then '<stdout>'
639
+ when $stdin then '<stdin>'
640
+ when $stderr then '<stderr>'
641
+ when Array
642
+ default.join(', ')
643
+ else
644
+ default.to_s
645
+ end
646
+ defword = desc.end_with?('.') ? 'Default' : 'default'
647
+ return "#{desc} (#{defword}: #{default_s})"
648
+ end
649
+
650
+ ## Provide a way to register symbol aliases to the Parser
651
+ def self.register_alias(*alias_keys)
652
+ alias_keys.each do |alias_key|
653
+ # pass in the alias-key and the class
654
+ Parser.register(alias_key, self)
682
655
  end
656
+ end
683
657
 
684
- type_from_default =
685
- case disambiguated_default
686
- when Integer then :int
687
- when Numeric then :float
688
- when TrueClass,
689
- FalseClass then :flag
690
- when String then :string
691
- when IO then :io
692
- when Date then :date
693
- when Array
694
- if opts[:default].empty?
695
- if opts[:type]
696
- raise ArgumentError, "multiple argument type must be plural" unless MULTI_ARG_TYPES.include?(opts[:type])
697
- nil
698
- else
699
- raise ArgumentError, "multiple argument type cannot be deduced from an empty array for '#{opts[:default][0].class.name}'"
700
- end
701
- else
702
- case opts[:default][0] # the first element determines the types
703
- when Integer then :ints
704
- when Numeric then :floats
705
- when String then :strings
706
- when IO then :ios
707
- when Date then :dates
708
- else
709
- raise ArgumentError, "unsupported multiple argument type '#{opts[:default][0].class.name}'"
710
- end
711
- end
712
- when nil then nil
713
- else
714
- raise ArgumentError, "unsupported argument type '#{opts[:default].class.name}'"
715
- end
658
+ ## Factory class methods ...
659
+
660
+ # Determines which type of object to create based on arguments passed
661
+ # to +Optimist::opt+. This is trickier in Optimist, than other cmdline
662
+ # parsers (e.g. Slop) because we allow the +default:+ to be able to
663
+ # set the option's type.
664
+ def self.create(name, desc="", opts={}, settings={})
665
+
666
+ opttype = Optimist::Parser.registry_getopttype(opts[:type])
667
+ opttype_from_default = get_klass_from_default(opts, opttype)
716
668
 
717
- raise ArgumentError, ":type specification and default type don't match (default type is #{type_from_default})" if opts[:type] && type_from_default && opts[:type] != type_from_default
669
+ raise ArgumentError, ":type specification and default type don't match (default type is #{opttype_from_default.class})" if opttype && opttype_from_default && (opttype.class != opttype_from_default.class)
718
670
 
719
- opts[:type] = opts[:type] || type_from_default || :flag
671
+ opt_inst = (opttype || opttype_from_default || Optimist::BooleanOption.new)
720
672
 
721
673
  ## fill in :long
722
- opts[:long] = opts[:long] ? opts[:long].to_s : name.to_s.gsub("_", "-")
723
- opts[:long] = case opts[:long]
724
- when /^--([^-].*)$/ then $1
725
- when /^[^-]/ then opts[:long]
726
- else raise ArgumentError, "invalid long option name #{opts[:long].inspect}"
727
- end
674
+ opt_inst.long = handle_long_opt(opts[:long], name)
728
675
 
729
676
  ## fill in :short
730
- opts[:short] = opts[:short].to_s if opts[:short] && opts[:short] != :none
731
- opts[:short] = case opts[:short]
732
- when /^-(.)$/ then $1
733
- when nil, :none, /^.$/ then opts[:short]
734
- else raise ArgumentError, "invalid short option name '#{opts[:short].inspect}'"
735
- end
677
+ opt_inst.short = handle_short_opt(opts[:short])
736
678
 
737
- if opts[:short]
738
- raise ArgumentError, "a short option name can't be a number or a dash" if opts[:short] =~ ::Trollop::Parser::INVALID_SHORT_ARG_REGEX
739
- end
679
+ ## fill in :multi
680
+ multi_given = opts[:multi] || false
681
+ opt_inst.multi_given = multi_given
740
682
 
741
683
  ## fill in :default for flags
742
- opts[:default] = false if opts[:type] == :flag && opts[:default].nil?
684
+ defvalue = opts[:default] || opt_inst.default
743
685
 
744
686
  ## autobox :default for :multi (multi-occurrence) arguments
745
- opts[:default] = [opts[:default]] if opts[:default] && opts[:multi] && !opts[:default].kind_of?(Array)
687
+ defvalue = [defvalue] if defvalue && multi_given && !defvalue.kind_of?(Array)
688
+ opt_inst.default = defvalue
689
+ opt_inst.name = name
690
+ opt_inst.opts = opts
691
+ opt_inst
692
+ end
746
693
 
747
- ## fill in :multi
748
- opts[:multi] ||= false
694
+ private
749
695
 
750
- self.name = name
751
- self.opts = opts
696
+ def self.get_type_from_disdef(optdef, opttype, disambiguated_default)
697
+ if disambiguated_default.is_a? Array
698
+ return(optdef.first.class.name.downcase + "s") if !optdef.empty?
699
+ if opttype
700
+ raise ArgumentError, "multiple argument type must be plural" unless opttype.multi_arg?
701
+ return nil
702
+ else
703
+ raise ArgumentError, "multiple argument type cannot be deduced from an empty array"
704
+ end
705
+ end
706
+ return disambiguated_default.class.name.downcase
752
707
  end
753
708
 
754
- def key?(name)
755
- opts.key?(name)
709
+ def self.get_klass_from_default(opts, opttype)
710
+ ## for options with :multi => true, an array default doesn't imply
711
+ ## a multi-valued argument. for that you have to specify a :type
712
+ ## as well. (this is how we disambiguate an ambiguous situation;
713
+ ## see the docs for Parser#opt for details.)
714
+
715
+ disambiguated_default = if opts[:multi] && opts[:default].is_a?(Array) && opttype.nil?
716
+ opts[:default].first
717
+ else
718
+ opts[:default]
719
+ end
720
+
721
+ return nil if disambiguated_default.nil?
722
+ type_from_default = get_type_from_disdef(opts[:default], opttype, disambiguated_default)
723
+ return Optimist::Parser.registry_getopttype(type_from_default)
756
724
  end
757
725
 
758
- def type ; opts[:type] ; end
759
- def flag? ; type == :flag ; end
760
- def single_arg?
761
- SINGLE_ARG_TYPES.include?(type)
726
+ def self.handle_long_opt(lopt, name)
727
+ lopt = lopt ? lopt.to_s : name.to_s.gsub("_", "-")
728
+ lopt = case lopt
729
+ when /^--([^-].*)$/ then $1
730
+ when /^[^-]/ then lopt
731
+ else raise ArgumentError, "invalid long option name #{lopt.inspect}"
732
+ end
762
733
  end
763
734
 
764
- def multi ; opts[:multi] ; end
765
- alias multi? multi
735
+ def self.handle_short_opt(sopt)
736
+ sopt = sopt.to_s if sopt && sopt != :none
737
+ sopt = case sopt
738
+ when /^-(.)$/ then $1
739
+ when nil, :none, /^.$/ then sopt
740
+ else raise ArgumentError, "invalid short option name '#{sopt.inspect}'"
741
+ end
766
742
 
767
- def multi_arg?
768
- MULTI_ARG_TYPES.include?(type)
743
+ if sopt
744
+ raise ArgumentError, "a short option name can't be a number or a dash" if sopt =~ ::Optimist::Parser::INVALID_SHORT_ARG_REGEX
745
+ end
746
+ return sopt
769
747
  end
770
748
 
771
- def default ; opts[:default] ; end
772
- #? def multi_default ; opts.default || opts.multi && [] ; end
773
- def array_default? ; opts[:default].kind_of?(Array) ; end
749
+ end
774
750
 
775
- def short ; opts[:short] ; end
776
- def short? ; short && short != :none ; end
777
- # not thrilled about this
778
- def short=(val) ; opts[:short] = val ; end
779
- def long ; opts[:long] ; end
780
- def callback ; opts[:callback] ; end
781
- def desc ; opts[:desc] ; end
751
+ # Flag option. Has no arguments. Can be negated with "no-".
752
+ class BooleanOption < Option
753
+ register_alias :flag, :bool, :boolean, :trueclass, :falseclass
754
+ def initialize
755
+ super()
756
+ @default = false
757
+ end
758
+ def flag? ; true ; end
759
+ def parse(_paramlist, neg_given)
760
+ return(self.name.to_s =~ /^no_/ ? neg_given : !neg_given)
761
+ end
762
+ end
763
+
764
+ # Floating point number option class.
765
+ class FloatOption < Option
766
+ register_alias :float, :double
767
+ def type_format ; "=<f>" ; end
768
+ def parse(paramlist, _neg_given)
769
+ paramlist.map do |pg|
770
+ pg.map do |param|
771
+ raise CommandlineError, "option '#{self.name}' needs a floating-point number" unless param.is_a?(Numeric) || param =~ FLOAT_RE
772
+ param.to_f
773
+ end
774
+ end
775
+ end
776
+ end
777
+
778
+ # Integer number option class.
779
+ class IntegerOption < Option
780
+ register_alias :int, :integer, :fixnum
781
+ def type_format ; "=<i>" ; end
782
+ def parse(paramlist, _neg_given)
783
+ paramlist.map do |pg|
784
+ pg.map do |param|
785
+ raise CommandlineError, "option '#{self.name}' needs an integer" unless param.is_a?(Numeric) || param =~ /^-?[\d_]+$/
786
+ param.to_i
787
+ end
788
+ end
789
+ end
790
+ end
791
+
792
+ # Option class for handling IO objects and URLs.
793
+ # Note that this will return the file-handle, not the file-name
794
+ # in the case of file-paths given to it.
795
+ class IOOption < Option
796
+ register_alias :io
797
+ def type_format ; "=<filename/uri>" ; end
798
+ def parse(paramlist, _neg_given)
799
+ paramlist.map do |pg|
800
+ pg.map do |param|
801
+ if param =~ /^(stdin|-)$/i
802
+ $stdin
803
+ else
804
+ require 'open-uri'
805
+ begin
806
+ open param
807
+ rescue SystemCallError => e
808
+ raise CommandlineError, "file or url for option '#{self.name}' cannot be opened: #{e.message}"
809
+ end
810
+ end
811
+ end
812
+ end
813
+ end
814
+ end
782
815
 
783
- def required? ; opts[:required] ; end
816
+ # Option class for handling Strings.
817
+ class StringOption < Option
818
+ register_alias :string
819
+ def type_format ; "=<s>" ; end
820
+ def parse(paramlist, _neg_given)
821
+ paramlist.map { |pg| pg.map(&:to_s) }
822
+ end
823
+ end
784
824
 
785
- def self.create(name, desc="", opts={})
786
- new(name, desc, opts)
825
+ # Option for dates. Uses Chronic if it exists.
826
+ class DateOption < Option
827
+ register_alias :date
828
+ def type_format ; "=<date>" ; end
829
+ def parse(paramlist, _neg_given)
830
+ paramlist.map do |pg|
831
+ pg.map do |param|
832
+ next param if param.is_a?(Date)
833
+ begin
834
+ begin
835
+ require 'chronic'
836
+ time = Chronic.parse(param)
837
+ rescue LoadError
838
+ # chronic is not available
839
+ end
840
+ time ? Date.new(time.year, time.month, time.day) : Date.parse(param)
841
+ rescue ArgumentError
842
+ raise CommandlineError, "option '#{self.name}' needs a date"
843
+ end
844
+ end
845
+ end
787
846
  end
788
847
  end
789
848
 
790
- ## The easy, syntactic-sugary entry method into Trollop. Creates a Parser,
849
+ ### MULTI_OPT_TYPES :
850
+ ## The set of values that indicate a multiple-parameter option (i.e., that
851
+ ## takes multiple space-separated values on the commandline) when passed as
852
+ ## the +:type+ parameter of #opt.
853
+
854
+ # Option class for handling multiple Integers
855
+ class IntegerArrayOption < IntegerOption
856
+ register_alias :fixnums, :ints, :integers
857
+ def type_format ; "=<i+>" ; end
858
+ def multi_arg? ; true ; end
859
+ end
860
+
861
+ # Option class for handling multiple Floats
862
+ class FloatArrayOption < FloatOption
863
+ register_alias :doubles, :floats
864
+ def type_format ; "=<f+>" ; end
865
+ def multi_arg? ; true ; end
866
+ end
867
+
868
+ # Option class for handling multiple Strings
869
+ class StringArrayOption < StringOption
870
+ register_alias :strings
871
+ def type_format ; "=<s+>" ; end
872
+ def multi_arg? ; true ; end
873
+ end
874
+
875
+ # Option class for handling multiple dates
876
+ class DateArrayOption < DateOption
877
+ register_alias :dates
878
+ def type_format ; "=<date+>" ; end
879
+ def multi_arg? ; true ; end
880
+ end
881
+
882
+ # Option class for handling Files/URLs via 'open'
883
+ class IOArrayOption < IOOption
884
+ register_alias :ios
885
+ def type_format ; "=<filename/uri+>" ; end
886
+ def multi_arg? ; true ; end
887
+ end
888
+
889
+ ## The easy, syntactic-sugary entry method into Optimist. Creates a Parser,
791
890
  ## passes the block to it, then parses +args+ with it, handling any errors or
792
891
  ## requests for help or version information appropriately (and then exiting).
793
892
  ## Modifies +args+ in place. Returns a hash of option values.
@@ -804,8 +903,8 @@ end
804
903
  ##
805
904
  ## Example:
806
905
  ##
807
- ## require 'trollop'
808
- ## opts = Trollop::options do
906
+ ## require 'optimist'
907
+ ## opts = Optimist::options do
809
908
  ## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
810
909
  ## opt :name, "Monkey name", :type => :string # a string --name <s>, defaulting to nil
811
910
  ## opt :num_limbs, "Number of limbs", :default => 4 # an integer --num-limbs <i>, defaulting to 4
@@ -817,13 +916,13 @@ end
817
916
  ## ## if called with --monkey
818
917
  ## p opts # => {:monkey=>true, :name=>nil, :num_limbs=>4, :help=>false, :monkey_given=>true}
819
918
  ##
820
- ## See more examples at http://trollop.rubyforge.org.
919
+ ## See more examples at http://optimist.rubyforge.org.
821
920
  def options(args = ARGV, *a, &b)
822
921
  @last_parser = Parser.new(*a, &b)
823
922
  with_standard_exception_handling(@last_parser) { @last_parser.parse args }
824
923
  end
825
924
 
826
- ## If Trollop::options doesn't do quite what you want, you can create a Parser
925
+ ## If Optimist::options doesn't do quite what you want, you can create a Parser
827
926
  ## object and call Parser#parse on it. That method will throw CommandlineError,
828
927
  ## HelpNeeded and VersionNeeded exceptions when necessary; if you want to
829
928
  ## have these handled for you in the standard manner (e.g. show the help
@@ -834,15 +933,15 @@ end
834
933
  ##
835
934
  ## Usage example:
836
935
  ##
837
- ## require 'trollop'
838
- ## p = Trollop::Parser.new do
936
+ ## require 'optimist'
937
+ ## p = Optimist::Parser.new do
839
938
  ## opt :monkey, "Use monkey mode" # a flag --monkey, defaulting to false
840
939
  ## opt :goat, "Use goat mode", :default => true # a flag --goat, defaulting to true
841
940
  ## end
842
941
  ##
843
- ## opts = Trollop::with_standard_exception_handling p do
942
+ ## opts = Optimist::with_standard_exception_handling p do
844
943
  ## o = p.parse ARGV
845
- ## raise Trollop::HelpNeeded if ARGV.empty? # show help screen
944
+ ## raise Optimist::HelpNeeded if ARGV.empty? # show help screen
846
945
  ## o
847
946
  ## end
848
947
  ##
@@ -877,12 +976,16 @@ end
877
976
  ## opt :whatever # ...
878
977
  ## end
879
978
  ##
880
- ## Trollop::die "need at least one filename" if ARGV.empty?
979
+ ## Optimist::die "need at least one filename" if ARGV.empty?
980
+ ##
981
+ ## An exit code can be provide if needed
982
+ ##
983
+ ## Optimist::die "need at least one filename", -2 if ARGV.empty?
881
984
  def die(arg, msg = nil, error_code = nil)
882
985
  if @last_parser
883
986
  @last_parser.die arg, msg, error_code
884
987
  else
885
- raise ArgumentError, "Trollop::die can only be called after Trollop::options"
988
+ raise ArgumentError, "Optimist::die can only be called after Optimist::options"
886
989
  end
887
990
  end
888
991
 
@@ -897,15 +1000,15 @@ end
897
1000
  ## EOS
898
1001
  ## end
899
1002
  ##
900
- ## Trollop::educate if ARGV.empty?
1003
+ ## Optimist::educate if ARGV.empty?
901
1004
  def educate
902
1005
  if @last_parser
903
1006
  @last_parser.educate
904
1007
  exit
905
1008
  else
906
- raise ArgumentError, "Trollop::educate can only be called after Trollop::options"
1009
+ raise ArgumentError, "Optimist::educate can only be called after Optimist::options"
907
1010
  end
908
1011
  end
909
1012
 
910
1013
  module_function :options, :die, :educate, :with_standard_exception_handling
911
- end # module
1014
+ end # module
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: darksky-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken J.
@@ -10,7 +10,7 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-09-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Darksky library written in pure Ruby without external dependency.
13
+ description: Dark Sky gem written in pure Ruby without any external dependency.
14
14
  email:
15
15
  - kenjij@gmail.com
16
16
  executables:
@@ -18,13 +18,14 @@ executables:
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - LICENSE
22
+ - README.md
21
23
  - bin/darksky
22
24
  - darksky-ruby.gemspec
23
25
  - lib/darksky-ruby.rb
24
26
  - lib/darksky-ruby/api.rb
25
27
  - lib/darksky-ruby/http.rb
26
- - lib/darksky-ruby/trollop.rb
27
- - lib/darksky-ruby/version.rb
28
+ - lib/darksky-ruby/optimist.rb
28
29
  homepage: https://github.com/kenjij/darksky-ruby
29
30
  licenses:
30
31
  - MIT
@@ -44,9 +45,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
45
  - !ruby/object:Gem::Version
45
46
  version: '0'
46
47
  requirements: []
47
- rubyforge_project:
48
- rubygems_version: 2.6.14
48
+ rubygems_version: 3.0.6
49
49
  signing_key:
50
50
  specification_version: 4
51
- summary: Pure simple Ruby based Darksky REST library
51
+ summary: Pure simple Ruby based Dark Sky API gem
52
52
  test_files: []
@@ -1,5 +0,0 @@
1
- module Darksky
2
-
3
- Version = '0.0.2'
4
-
5
- end