rbcli 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +13 -1
- data/README.md +80 -2
- data/examples/mytool +3 -0
- data/lib/rbcli.rb +4 -0
- data/lib/rbcli/autoupdate/autoupdate.rb +46 -0
- data/lib/rbcli/autoupdate/gem_updater.rb +37 -0
- data/lib/rbcli/autoupdate/github_updater.rb +48 -0
- data/lib/rbcli/engine/parser.rb +1 -1
- data/lib/rbcli/stateful_systems/state_storage.rb +42 -17
- data/lib/rbcli/stateful_systems/storagetypes/remote_state_connectors/dynamodb.rb +17 -5
- data/lib/rbcli/version.rb +1 -1
- data/rbcli.gemspec +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0eefbfff220d04c6c6093ea0d3ec5cdd8fe93a6f02568c720ed04baddf05a25b
|
4
|
+
data.tar.gz: b7d18d8c85c131cd57c7cc78d63656687896bd02f0bb4d84c8e65a0bc332a7f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28893fa34a3e02a1f67b1279b88fb52812f07601ec9dc20662f15351d55ea06c2a4bc401a7fce9c2877b7eccfc4165183b7a6770c171084114eac2228cb49288
|
7
|
+
data.tar.gz: 96cb8d64eabc9d48e511d1923e174b31c3f1d3f4fd9f74345c3cf19209ff21c3837bc6166ed97ea4b962a089cdfb9efcffea54efa923e9b3f60786e91cb0e249
|
data/Gemfile.lock
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rbcli (0.1.
|
4
|
+
rbcli (0.1.5)
|
5
5
|
aws-sdk-dynamodb (~> 1.6)
|
6
6
|
colorize (~> 0.8)
|
7
7
|
deep_merge (~> 1.2)
|
8
8
|
macaddr (~> 1.7)
|
9
|
+
octokit (~> 4.9)
|
9
10
|
rufus-scheduler (~> 3.5)
|
10
11
|
|
11
12
|
GEM
|
12
13
|
remote: https://rubygems.org/
|
13
14
|
specs:
|
15
|
+
addressable (2.5.2)
|
16
|
+
public_suffix (>= 2.0.2, < 4.0)
|
14
17
|
aws-eventstream (1.0.0)
|
15
18
|
aws-partitions (1.87.0)
|
16
19
|
aws-sdk-core (3.21.2)
|
@@ -26,6 +29,8 @@ GEM
|
|
26
29
|
deep_merge (1.2.1)
|
27
30
|
et-orbi (1.1.2)
|
28
31
|
tzinfo
|
32
|
+
faraday (0.15.2)
|
33
|
+
multipart-post (>= 1.2, < 3)
|
29
34
|
fugit (1.1.1)
|
30
35
|
et-orbi (~> 1.1, >= 1.1.1)
|
31
36
|
raabro (~> 1.1)
|
@@ -33,10 +38,17 @@ GEM
|
|
33
38
|
macaddr (1.7.1)
|
34
39
|
systemu (~> 2.6.2)
|
35
40
|
minitest (5.11.3)
|
41
|
+
multipart-post (2.0.0)
|
42
|
+
octokit (4.9.0)
|
43
|
+
sawyer (~> 0.8.0, >= 0.5.3)
|
44
|
+
public_suffix (3.0.2)
|
36
45
|
raabro (1.1.5)
|
37
46
|
rake (10.5.0)
|
38
47
|
rufus-scheduler (3.5.0)
|
39
48
|
fugit (~> 1.1, >= 1.1.1)
|
49
|
+
sawyer (0.8.1)
|
50
|
+
addressable (>= 2.3.5, < 2.6)
|
51
|
+
faraday (~> 0.8, < 1.0)
|
40
52
|
systemu (2.6.5)
|
41
53
|
thread_safe (0.3.6)
|
42
54
|
tzinfo (1.2.5)
|
data/README.md
CHANGED
@@ -20,6 +20,8 @@ Some of its key features include:
|
|
20
20
|
|
21
21
|
* __State Locking and Sharing__: Share remote state safely between users with built-in locking! When enabled, it makes sure that only one user is accessing the data at any given time.
|
22
22
|
|
23
|
+
* __Automatic Update Notifications__: Just provide the gem name or git repo, and RBCli will take care of notifying users!
|
24
|
+
|
23
25
|
## Installation
|
24
26
|
|
25
27
|
RBCli is available on rubygems.org. You can add it to your application's `Gemrile` or `gemspec`, or install it manually via `gem install rbcli`.
|
@@ -80,6 +82,9 @@ Rbcli::Configurate.me do
|
|
80
82
|
|
81
83
|
option :name, 'Give me your name', type: :string, default: 'Foo', required: false, permitted: ['Jack', 'Jill'] # (Optional, Multiple) Add a global CLI parameter. Supported types are :string, :boolean, :integer, :float, :date, and :io. Can be called multiple times.
|
82
84
|
|
85
|
+
autoupdate github_repo: 'akhoury6/rbcli', access_token: nil, enterprise_hostname: nil, this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application at a GitHub repo. The repo must use version number tags in accordance to best practices: https://help.github.com/articles/creating-releases/
|
86
|
+
autoupdate gem: 'rbcli', this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application through RubyGems.org.
|
87
|
+
|
83
88
|
default_action do |opts| # (Optional) The default code to execute when no subcommand is given. If not present, the help is shown (same as -h)
|
84
89
|
puts "Hello, #{opts[:name]}."
|
85
90
|
puts "To see the help, use -h"
|
@@ -247,7 +252,25 @@ Once configured you can access it with a standard hash syntax:
|
|
247
252
|
Rbcli.local_state[:yourkeyhere]
|
248
253
|
```
|
249
254
|
|
250
|
-
For performance reasons, the only methods available for use are
|
255
|
+
For performance reasons, the only methods available for use are:
|
256
|
+
|
257
|
+
Hash native methods:
|
258
|
+
|
259
|
+
* `[]` (Regular hash syntax. Keys are accessed via either symbols or strings indifferently.)
|
260
|
+
* `[]=` (Assignment operator)
|
261
|
+
* `delete`
|
262
|
+
* `each`
|
263
|
+
* `key?`
|
264
|
+
|
265
|
+
Additional methods:
|
266
|
+
|
267
|
+
* `clear`
|
268
|
+
* Resets the data back to an empty hash.
|
269
|
+
* `refresh`
|
270
|
+
* Loads the most current version of the data from the disk
|
271
|
+
* `disconnect`
|
272
|
+
* Removes the data from memory and sets `Rbcli.local_state = nil`. Data will be read from disk again on next access.
|
273
|
+
|
251
274
|
|
252
275
|
Every assignment will result in a write to disk, so if an operation will require a large number of assignments/writes it should be performed to a different hash before beign assigned to this one.
|
253
276
|
|
@@ -282,6 +305,8 @@ Rbcli.remote_state[:yourkeyhere]
|
|
282
305
|
|
283
306
|
This works the same way that [Local State](#local_state) does, with the same performance caveats (try not to do many writes!).
|
284
307
|
|
308
|
+
Note that all state in Rbcli is __lazy-loaded__, so no connections will be made until your code attempts to access the data.
|
309
|
+
|
285
310
|
#### DynamoDB Configuration
|
286
311
|
|
287
312
|
Before DynamoDB can be used, AWS API credentials have to be created and made available. RBCli will attempt to find credentials from the following locations in order:
|
@@ -317,7 +342,7 @@ Distributed Locking allows a remote state to be shared among multiple users of t
|
|
317
342
|
|
318
343
|
This is how locking works:
|
319
344
|
|
320
|
-
1. The application attempts to acquire a lock on the remote state when it
|
345
|
+
1. The application attempts to acquire a lock on the remote state when you first access it
|
321
346
|
2. If the backend is locked by a different application, wait and try again
|
322
347
|
3. If it succeeds, the lock is held and refreshed periodically
|
323
348
|
4. When the application exits, the lock is released
|
@@ -325,6 +350,59 @@ This is how locking works:
|
|
325
350
|
6. If another application steals the lock (unlikely but possible), and the application tries to save data, a `StandardError` will be thrown
|
326
351
|
7. You can manually attempt to lock/unlock by calling `Rbcli.remote_state.lock` or `Rbcli.remote_state.unlock`, respectively.
|
327
352
|
|
353
|
+
##### Auto-locking vs Manual Locking
|
354
|
+
|
355
|
+
Remember: all state in Rbcli is lazy-loaded. Therefore, RBCli wll only attempt to lock the data when you first try to access it. If you need to make sure that the data is locked before executing a block of code, use:
|
356
|
+
|
357
|
+
```ruby
|
358
|
+
Rbcli.remote_state.refresh
|
359
|
+
```
|
360
|
+
|
361
|
+
to force the lock and retrieve the latest data. You can force an unlock by calling:
|
362
|
+
|
363
|
+
```ruby
|
364
|
+
Rbcli.remote_state.disconnect
|
365
|
+
```
|
366
|
+
|
367
|
+
## Automatic Update Check
|
368
|
+
|
369
|
+
RBCli can automatically notify users when an update is available. If `force_update` is set (see below), RBCli can halt execution until the user updates their application.
|
370
|
+
|
371
|
+
Two sources are currently supported: Github (including Enterprise) and RubyGems.
|
372
|
+
|
373
|
+
### GitHub Update Check
|
374
|
+
|
375
|
+
The GitHub update check works best when paired with GitHub's best practices on releases. See here: https://help.github.com/articles/creating-releases/
|
376
|
+
|
377
|
+
RBCli will check your github repo's tags and compare that version number with one embedded into your code. In this example, we are leveraging the version number that we also use for RBCli's gemspec:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
autoupdate github_repo: 'akhoury6/rbcli', access_token: nil, enterprise_hostname: nil, this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application at a GitHub repo. The repo must use version number tags in accordance to best practices: https://help.github.com/articles/creating-releases/
|
381
|
+
```
|
382
|
+
The `github_repo` should point to the repo using the `user/repo` syntax.
|
383
|
+
|
384
|
+
The `access_token` can be overridden by the user via their configuration file, so it can be left as `nil`. The token is not needed at all if using a public repo. For instructions on generating a new access token, see [here](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/).
|
385
|
+
|
386
|
+
The `enterprise_hostname` setting allows you to point RBCli at a local GitHub Enterprise server.
|
387
|
+
|
388
|
+
The `this_version` parameter should be set to the current version of the tool that the user is running. Here we leverage the default version location that is used for the RBCli gem itself. In your tool, you should replace this with your own version number.
|
389
|
+
|
390
|
+
Setting `force_update: true` will halt execution if an update is available, forcing the user to update.
|
391
|
+
|
392
|
+
### Rubygems.org Update Check
|
393
|
+
|
394
|
+
The Rubygems update check will check if there is a new published version of the gem on Rubygems.org.
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
autoupdate gem: 'rbcli', this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application through RubyGems.org.
|
398
|
+
```
|
399
|
+
|
400
|
+
The `gem` parameter should simply state the name of the gem.
|
401
|
+
|
402
|
+
The `this_version` parameter should be set to the current version of the tool that the user is running. Here we leverage the default version location that is used for the RBCli gem itself. In your tool, you should replace this with your own version number.
|
403
|
+
|
404
|
+
Setting `force_update: true` will halt execution if an update is available, forcing the user to update.
|
405
|
+
|
328
406
|
## Development
|
329
407
|
|
330
408
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/examples/mytool
CHANGED
@@ -22,6 +22,9 @@ Rbcli::Configurate.me do
|
|
22
22
|
|
23
23
|
option :name, 'Give me your name', type: :string, default: 'Foo', required: false, permitted: ['Jack', 'Jill'] # (Optional, Multiple) Add a global CLI parameter. Supported types are :string, :boolean, :integer, :float, :date, and :io. Can be called multiple times.
|
24
24
|
|
25
|
+
autoupdate github_repo: 'akhoury6/rbcli', access_token: nil, enterprise_hostname: nil, this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application at a GitHub repo. The repo must use version number tags in accordance to best practices: https://help.github.com/articles/creating-releases/
|
26
|
+
autoupdate gem: 'rbcli', this_version: Rbcli::VERSION, force_update: false # (Optional) Check for updates to this application through RubyGems.org.
|
27
|
+
|
25
28
|
default_action do |opts| # (Optional) The default code to execute when no subcommand is given. If not present, the help is shown (same as -h)
|
26
29
|
puts "Hello, #{opts[:name]}."
|
27
30
|
puts "To see the help, use -h"
|
data/lib/rbcli.rb
CHANGED
@@ -13,6 +13,10 @@ require "rbcli/stateful_systems/storagetypes/localstate"
|
|
13
13
|
require "rbcli/stateful_systems/storagetypes/remotestate_dynamodb"
|
14
14
|
# END STATE TOOLS
|
15
15
|
|
16
|
+
# AUTOUPDATE
|
17
|
+
require "rbcli/autoupdate/autoupdate"
|
18
|
+
# END AUTOUPDATE
|
19
|
+
|
16
20
|
require "rbcli/configurate"
|
17
21
|
|
18
22
|
require "rbcli/engine/command"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Rbcli::Configurate
|
2
|
+
def self.autoupdate gem: nil, github_repo: nil, access_token: nil, enterprise_hostname: nil, this_version: nil, force_update: false
|
3
|
+
raise StandardError.new "Autoupdater can not have both a gem and git target defined. Please pick one." if gem and giturl
|
4
|
+
raise StandardError.new "Only one autoupdater can be defined." if @data[:autoupdater]
|
5
|
+
if gem
|
6
|
+
#Rbcli::Autoupdate::GemUpdater.save_defaults
|
7
|
+
@data[:autoupdater] = Rbcli::Autoupdate::GemUpdater.new gem, this_version, force_update
|
8
|
+
else
|
9
|
+
Rbcli::Autoupdate::GithubUpdater.save_defaults
|
10
|
+
@data[:autoupdater] = Rbcli::Autoupdate::GithubUpdater.new github_repo, access_token, enterprise_hostname, this_version, force_update
|
11
|
+
end
|
12
|
+
@data[:autoupdater].show_message if @data[:autoupdater].update_available?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
module Rbcli::Autoupdate
|
19
|
+
module Common
|
20
|
+
def get_latest_version
|
21
|
+
raise Exception.new "Autoupdater type #{self.class.name} must define a 'check_for_updates' method."
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_message
|
25
|
+
raise Exception.new "Autoupdater type #{self.class.name} must define an 'update_message' method."
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_available?
|
29
|
+
@latest_version = get_latest_version
|
30
|
+
Gem::Version.new(@latest_version) > Gem::Version.new(@this_version)
|
31
|
+
end
|
32
|
+
|
33
|
+
def show_message
|
34
|
+
puts "WARNING: An update is available to #{Rbcli::Configurate::configuration[:scriptname]}. You are currently running version #{@this_version}; the latest is #{@latest_version || get_latest_version}."
|
35
|
+
puts update_message
|
36
|
+
puts "\n"
|
37
|
+
if @force_update
|
38
|
+
puts "This application requires that you update to the latest version to continue using it. It will now exit."
|
39
|
+
exit 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require "rbcli/autoupdate/gem_updater"
|
46
|
+
require "rbcli/autoupdate/github_updater"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Rbcli::Autoupdate
|
5
|
+
class GemUpdater
|
6
|
+
include Common
|
7
|
+
|
8
|
+
def initialize gemname, this_version, force_update
|
9
|
+
@gemname = gemname
|
10
|
+
@uri = URI.parse "https://rubygems.org/api/v1/versions/#{gemname}/latest.json"
|
11
|
+
@this_version = this_version
|
12
|
+
@force_update = force_update
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_latest_version
|
16
|
+
response = Net::HTTP.get(@uri)
|
17
|
+
JSON.parse(response)['version']
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_message
|
21
|
+
"Please check the Ruby gem #{@gemname} for instructions. You can see it at: https://rubygems.org/gems/#{@gemname}/versions/#{@latest_version}"
|
22
|
+
end
|
23
|
+
|
24
|
+
# def self.save_defaults
|
25
|
+
# Rbcli::Config::add_categorized_defaults :gem_update, 'Automatically Check for Updates from RubyGems', {
|
26
|
+
# access_token: {
|
27
|
+
# description: 'Access token for GitHub API. This is only required for private repos. For help, see: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/',
|
28
|
+
# value: nil
|
29
|
+
# },
|
30
|
+
# enterprise_hostname: {
|
31
|
+
# description: 'Hostname for GitHub Enterprise. Leave as null (~) for public GitHub.',
|
32
|
+
# value: nil
|
33
|
+
# }
|
34
|
+
# }
|
35
|
+
# end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module Rbcli::Autoupdate
|
4
|
+
class GithubUpdater
|
5
|
+
include Common
|
6
|
+
|
7
|
+
def initialize reponame, access_token, enterprise_hostname, this_version, force_update
|
8
|
+
@reponame = reponame
|
9
|
+
@this_version = this_version
|
10
|
+
@force_update = force_update
|
11
|
+
|
12
|
+
access_token = Rbcli.config.key?(:github_updatecheck) ? (Rbcli.config[:github_updatecheck][:access_token] || access_token) : access_token
|
13
|
+
enterprise_hostname = Rbcli.config.key?(:github_updatecheck) ? (Rbcli.config[:github_updatecheck][:enterprise_hostname] || enterprise_hostname) : enterprise_hostname
|
14
|
+
|
15
|
+
# Enterprise Connection
|
16
|
+
if enterprise_hostname
|
17
|
+
Octokit.configure do |c|
|
18
|
+
c.api_endpoint = "https://#{enterprise_hostname}/api/v3/"
|
19
|
+
end
|
20
|
+
# Public Github Connection
|
21
|
+
end
|
22
|
+
#OAuth connection - not used
|
23
|
+
#@client = Octokit::Client.new :client_id => client_id, :client_secret => client_secret
|
24
|
+
@client = Octokit::Client.new(:access_token => access_token)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_latest_version
|
28
|
+
@client.repo(@reponame).rels[:tags].get.data.map{ |t| t[:name] }[0].sub(/^[v]*/,"")
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_message
|
32
|
+
"Please check the github repo #{@reponame} for instructions."
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.save_defaults
|
36
|
+
Rbcli::Config::add_categorized_defaults :github_update, 'Automatically Check for Updates from GitHub', {
|
37
|
+
access_token: {
|
38
|
+
description: 'Access token for GitHub API. This is only required for private repos. For help, see: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/',
|
39
|
+
value: nil
|
40
|
+
},
|
41
|
+
enterprise_hostname: {
|
42
|
+
description: 'Hostname for GitHub Enterprise. Leave as null (~) for public GitHub.',
|
43
|
+
value: nil
|
44
|
+
}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/rbcli/engine/parser.rb
CHANGED
@@ -48,7 +48,7 @@ Commands:
|
|
48
48
|
|
49
49
|
Rbcli.configuration[:pre_hook].call @cliopts unless Rbcli.configuration[:pre_hook].nil?
|
50
50
|
Rbcli::Command.runcmd(@cmd.shift, @cmd[0], @cliopts)
|
51
|
-
Rbcli.configuration[:post_hook].call @cliopts unless Rbcli.configuration[:
|
51
|
+
Rbcli.configuration[:post_hook].call @cliopts unless Rbcli.configuration[:post_hook].nil?
|
52
52
|
else
|
53
53
|
Trollop::die "Unknown subcommand #{@cmd[0].inspect}"
|
54
54
|
end
|
@@ -7,83 +7,108 @@ module Rbcli::State
|
|
7
7
|
## Main State Class
|
8
8
|
class StateStorage
|
9
9
|
|
10
|
-
def initialize path, force_creation: false, halt_on_error: true
|
10
|
+
def initialize path, force_creation: false, halt_on_error: true, lazy_load: true
|
11
11
|
@path = path
|
12
12
|
@force_creation = force_creation
|
13
13
|
@halt_on_error = halt_on_error
|
14
14
|
|
15
15
|
state_subsystem_init
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
21
|
-
|
22
|
-
if state_exists?
|
23
|
-
load_state
|
24
|
-
elsif force_creation
|
25
|
-
create_state
|
26
|
-
@data = base_data
|
27
|
-
save_state
|
28
|
-
else
|
29
|
-
raise StandardError "State location #{@path} does not exist or can not be accessed." if @halt_on_error
|
30
|
-
@data = base_data
|
31
|
-
end
|
17
|
+
# Lazy load option
|
18
|
+
@loaded = false
|
19
|
+
state_create unless lazy_load
|
32
20
|
end
|
33
21
|
|
34
22
|
def []= key, value
|
23
|
+
state_create unless @loaded
|
35
24
|
@data[:data][key.to_sym] = value
|
36
25
|
save_state
|
37
26
|
@data[:data][key.to_sym]
|
38
27
|
end
|
39
28
|
|
40
29
|
def [] key
|
30
|
+
state_create unless @loaded
|
41
31
|
@data[:data][key.to_sym]
|
42
32
|
end
|
43
33
|
|
44
34
|
def delete key, &block
|
35
|
+
state_create unless @loaded
|
45
36
|
result = @data[:data].delete key.to_sym, block
|
46
37
|
save_state
|
47
38
|
result
|
48
39
|
end
|
49
40
|
|
50
41
|
def refresh
|
51
|
-
|
42
|
+
if @loaded
|
43
|
+
load_state
|
44
|
+
else
|
45
|
+
state_create
|
46
|
+
end
|
52
47
|
end
|
53
48
|
|
54
49
|
def clear
|
50
|
+
state_create unless @loaded
|
55
51
|
@data[:data] = {}
|
56
52
|
save_state
|
57
53
|
end
|
58
54
|
|
55
|
+
def disconnect
|
56
|
+
unlock if self.class.method_defined? :unlock
|
57
|
+
@loaded = false
|
58
|
+
@data[:data] = nil
|
59
|
+
end
|
60
|
+
|
59
61
|
def each &block
|
62
|
+
state_create unless @loaded
|
60
63
|
@data[:data].each &block
|
61
64
|
save_state
|
62
65
|
end
|
63
66
|
|
64
67
|
def key? key
|
68
|
+
state_create unless @loaded
|
65
69
|
@data[:data].key? key.to_sym
|
66
70
|
end
|
67
71
|
|
68
72
|
def to_h
|
73
|
+
state_create unless @loaded
|
69
74
|
@data[:data]
|
70
75
|
end
|
71
76
|
|
72
77
|
def to_s
|
78
|
+
state_create unless @loaded
|
73
79
|
to_h.to_s
|
74
80
|
end
|
75
81
|
|
76
82
|
# For framework's internal use
|
77
83
|
|
78
84
|
def rbclidata key = nil
|
85
|
+
state_create unless @loaded
|
79
86
|
return @data[:rbcli][key.to_sym] unless key.nil?
|
80
87
|
@data[:rbcli]
|
81
88
|
end
|
82
89
|
|
83
90
|
def set_rbclidata key, value
|
91
|
+
state_create unless @loaded
|
84
92
|
@data[:rbcli][key.to_sym] = value
|
85
93
|
save_state
|
86
94
|
end
|
87
95
|
|
96
|
+
private
|
97
|
+
|
98
|
+
def state_create
|
99
|
+
base_data = {data: {}, rbcli: {}}
|
100
|
+
if state_exists?
|
101
|
+
load_state
|
102
|
+
elsif @force_creation
|
103
|
+
create_state
|
104
|
+
@data = base_data
|
105
|
+
save_state
|
106
|
+
else
|
107
|
+
raise StandardError "State location #{@path} does not exist or can not be accessed." if @halt_on_error
|
108
|
+
@data = base_data
|
109
|
+
end
|
110
|
+
@loaded = true
|
111
|
+
end
|
112
|
+
|
88
113
|
end
|
89
114
|
end
|
@@ -26,6 +26,8 @@ module Rbcli::State::RemoteConnectors
|
|
26
26
|
@locking = locking
|
27
27
|
@scheduler = nil
|
28
28
|
@lock_timeout = lock_timeout
|
29
|
+
@exit_code_set = false
|
30
|
+
@should_unlock_at_exit = false
|
29
31
|
|
30
32
|
@dynamo_client = Aws::DynamoDB::Client.new(
|
31
33
|
region: @region,
|
@@ -131,6 +133,7 @@ module Rbcli::State::RemoteConnectors
|
|
131
133
|
}
|
132
134
|
)
|
133
135
|
@scheduler.shutdown :kill if @scheduler
|
136
|
+
@should_unlock_at_exit = false
|
134
137
|
@scheduler = nil
|
135
138
|
end
|
136
139
|
|
@@ -190,8 +193,10 @@ module Rbcli::State::RemoteConnectors
|
|
190
193
|
lock
|
191
194
|
end
|
192
195
|
# We also make sure we release the lock at exit. In case this doesn't happen, the lock will expire on its own
|
193
|
-
|
194
|
-
|
196
|
+
@should_unlock_at_exit = true
|
197
|
+
unless @exit_code_set
|
198
|
+
at_exit {unlock if @should_unlock_at_exit}
|
199
|
+
@exit_code_set = true
|
195
200
|
end
|
196
201
|
end
|
197
202
|
puts 'done!' if recursed
|
@@ -204,7 +209,9 @@ module Rbcli::State::RemoteConnectors
|
|
204
209
|
|
205
210
|
end
|
206
211
|
|
207
|
-
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# END lock_or_wait
|
208
215
|
|
209
216
|
private
|
210
217
|
|
@@ -228,12 +235,17 @@ module Rbcli::State::RemoteConnectors
|
|
228
235
|
end
|
229
236
|
|
230
237
|
def get_lockdata
|
231
|
-
@dynamo_client.get_item(
|
238
|
+
item = @dynamo_client.get_item(
|
232
239
|
{
|
233
240
|
key: {'Script Name' => "#{@item_name}_lock"},
|
234
|
-
table_name: @dynamo_table_name
|
241
|
+
table_name: @dynamo_table_name
|
235
242
|
}
|
236
243
|
).item
|
244
|
+
if item.nil?
|
245
|
+
lock
|
246
|
+
return get_lockdata
|
247
|
+
end
|
248
|
+
item
|
237
249
|
end
|
238
250
|
|
239
251
|
end
|
data/lib/rbcli/version.rb
CHANGED
data/rbcli.gemspec
CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
|
|
43
43
|
spec.add_dependency 'aws-sdk-dynamodb', '~> 1.6'
|
44
44
|
spec.add_dependency 'macaddr', '~> 1.7'
|
45
45
|
spec.add_dependency 'rufus-scheduler', '~> 3.5'
|
46
|
+
spec.add_dependency 'octokit', '~> 4.9'
|
46
47
|
|
47
48
|
#spec.add_dependency 'trollop', '~> 2.1'
|
48
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Khoury
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '3.5'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: octokit
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '4.9'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '4.9'
|
125
139
|
description: RBCli is a framework to quickly develop command-line tools.
|
126
140
|
email:
|
127
141
|
- akhoury@live.com
|
@@ -144,6 +158,9 @@ files:
|
|
144
158
|
- examples/mytool
|
145
159
|
- exe/rbcli
|
146
160
|
- lib/rbcli.rb
|
161
|
+
- lib/rbcli/autoupdate/autoupdate.rb
|
162
|
+
- lib/rbcli/autoupdate/gem_updater.rb
|
163
|
+
- lib/rbcli/autoupdate/github_updater.rb
|
147
164
|
- lib/rbcli/configurate.rb
|
148
165
|
- lib/rbcli/engine/command.rb
|
149
166
|
- lib/rbcli/engine/parser.rb
|