vscripts 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +2 -0
- data/LICENSE +14 -0
- data/README.md +65 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/bin/vscripts +4 -0
- data/lib/vscripts.rb +12 -0
- data/lib/vscripts/aws.rb +10 -0
- data/lib/vscripts/aws/ec2.rb +69 -0
- data/lib/vscripts/aws/metadata.rb +50 -0
- data/lib/vscripts/command.rb +14 -0
- data/lib/vscripts/command_line.rb +72 -0
- data/lib/vscripts/commands/tags2facts.rb +84 -0
- data/lib/vscripts/util/local_system.rb +91 -0
- data/lib/vscripts/version.rb +6 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/vscripts/aws/ec2_spec.rb +81 -0
- data/spec/vscripts/aws/metadata_spec.rb +48 -0
- data/spec/vscripts/aws_spec.rb +7 -0
- data/spec/vscripts/command_line_spec.rb +34 -0
- data/spec/vscripts/command_spec.rb +9 -0
- data/spec/vscripts/commands/tags2facts_spec.rb +34 -0
- data/spec/vscripts/util/local_system_spec.rb +80 -0
- data/spec/vscripts/version_spec.rb +7 -0
- data/spec/vscripts_spec.rb +4 -0
- data/tasks/deploy.rake +95 -0
- data/tasks/lint.rake +22 -0
- data/vscripts.gemspec +35 -0
- metadata +270 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0d38d36783f6824793b72877c41ed04da154c492
|
4
|
+
data.tar.gz: e16339dde0ebe97ccba08c2698713a04b9f73431
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffb1d84f8a7c17162fa951b115579ac862503fda12662380db96d06af0afae7ed494d13ec6657cbf454efced85aa04eba5c6e5afe710547fd0033896e4a50668
|
7
|
+
data.tar.gz: 96f561e9331fbcf87a3738c46fea0729a642a8bcf6c2d55b5fcbc70dedab1aa3759a031a7ddcb353c6e23afa873e0f8eaa045ded9579ea4ca911218431533857
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Version 0.0.1
|
2
|
+
---
|
3
|
+
* Create gem structure ([Vlad - 635a06d](https://github.com/vghn/vscripts/commit/635a06d33fab5e8dbee39991ffc1e7bbf4ef4e6f))
|
4
|
+
* Copyright year ([Vlad - 5f11c06](https://github.com/vghn/vscripts/commit/5f11c0616e806af127a187740f845e0a23939211))
|
5
|
+
* Add clean tasks ([Vlad - 6675f56](https://github.com/vghn/vscripts/commit/6675f5649a797df8a74ffd2e3bbe7d1ec232321f))
|
6
|
+
* Simplify executable ([Vlad - 7ba96a8](https://github.com/vghn/vscripts/commit/7ba96a8a4e99b2c3f83bdc15cccfa5e66e825c44))
|
7
|
+
* Command line ([Vlad - ebb5dfb](https://github.com/vghn/vscripts/commit/ebb5dfb0c08e412d9e041ea80e1d05b957baaca0))
|
8
|
+
* Misc ([Vlad - ae012ec](https://github.com/vghn/vscripts/commit/ae012ec3d741bc8cc4cec19e4973b5f1ff1abff0))
|
9
|
+
* Update README ([Vlad - ded7d20](https://github.com/vghn/vscripts/commit/ded7d2081d643009c38e8fe51b860c8d9eb0880a))
|
10
|
+
* Tags2Facts command ([Vlad - 314e71b](https://github.com/vghn/vscripts/commit/314e71b242f4cb4fc0f27e440395cd2d04a55515))
|
11
|
+
* Travis ([Vlad - 3cc8938](https://github.com/vghn/vscripts/commit/3cc89389306b17faddf8cf51e02679138ef4c352))
|
12
|
+
* Travis Ruby 2.1.2 ([Vlad - b7c97ec](https://github.com/vghn/vscripts/commit/b7c97ecd9698065bf332ce9b9e5089aa2655fc5b))
|
13
|
+
* Update README ([Vlad - 81b5732](https://github.com/vghn/vscripts/commit/81b5732399ac8cccb295b77f43e0138f3909a46a))
|
14
|
+
* Travis spec ([Vlad - 5d45334](https://github.com/vghn/vscripts/commit/5d453348b2629208815109632d550d349e153daf))
|
15
|
+
* Fix tags hash ([Vlad - ca87f5f](https://github.com/vghn/vscripts/commit/ca87f5f329f27e18fa1b8bb64c013d417e99cb15))
|
16
|
+
* Add badges in README ([Vlad - df19aa8](https://github.com/vghn/vscripts/commit/df19aa86db8e589a89387828cb9da53e075c7438))
|
17
|
+
* Fix command case ([Vlad - abee006](https://github.com/vghn/vscripts/commit/abee006560a3983a8021d28ed95593e02e78e10a))
|
18
|
+
* Capitalize tags ([Vlad - 13fc4f2](https://github.com/vghn/vscripts/commit/13fc4f2d0f8982a74fd38b13deb593c4740d56bd))
|
19
|
+
* Minor fixes ([Vlad - 1ce2b34](https://github.com/vghn/vscripts/commit/1ce2b34d32dc8d24108b00c0ce8c04f2cc14495e))
|
20
|
+
* Fix code smells ([Vlad - 4da7c79](https://github.com/vghn/vscripts/commit/4da7c7938ee5250fe002fc2c23e66ec081f77ca5))
|
21
|
+
* Add rake dependency ([Vlad - e4a7b77](https://github.com/vghn/vscripts/commit/e4a7b77df57660372619084a903b13b26ff84258))
|
22
|
+
* Fix tags hash ([Vlad - cc9e175](https://github.com/vghn/vscripts/commit/cc9e175fbb48ba293ca278356fb755c15f31d3f7))
|
23
|
+
* Add automated deployment task ([Vlad - a113a4d](https://github.com/vghn/vscripts/commit/a113a4d9cacc51740daa5cde0294dad8ff297757))
|
24
|
+
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (C) 2014 Vlad Ghinea <vlad@ghn.me>
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
14
|
+
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# VScripts
|
2
|
+
[](https://travis-ci.org/vghn/vscripts)
|
3
|
+
[](https://codeclimate.com/github/vghn/vscripts)
|
4
|
+
|
5
|
+
Automation daemon.
|
6
|
+
|
7
|
+
## Dependencies
|
8
|
+
- Ruby >= 1.9.3
|
9
|
+
- An AWS account (you'll need to create):
|
10
|
+
- A SNS Queue (optional, will attempt to create if can't be found)
|
11
|
+
- A Route53 zone.
|
12
|
+
|
13
|
+
## Installing
|
14
|
+
|
15
|
+
### Gem installation
|
16
|
+
`gem install vscripts`
|
17
|
+
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```
|
22
|
+
vscripts GLOBAL-OPTIONS COMMAND OPTIONS
|
23
|
+
```
|
24
|
+
|
25
|
+
|
26
|
+
### Global Options:
|
27
|
+
```
|
28
|
+
-h|--help: Displays VScripts help.
|
29
|
+
-v|--version: Displays the version number.
|
30
|
+
```
|
31
|
+
|
32
|
+
|
33
|
+
### Commands:
|
34
|
+
|
35
|
+
1. **Tags2Facts**
|
36
|
+
This command can only be run on an AWS EC2 instance. It looks for all tags
|
37
|
+
associated with it and dumps them in a JSON file. By default this file is
|
38
|
+
`/etc/facter/facts.d/ec2_tags.json`. It can be overridden with the
|
39
|
+
***`--file`*** argument.
|
40
|
+
The `Name` and `Domain` tags are excluded by default because this command is
|
41
|
+
intended to add Facter facts and these 2 already exist in Facter. This behaviour
|
42
|
+
can be overridden by adding `[-a|--all]` command line option.
|
43
|
+
|
44
|
+
> **Options**:
|
45
|
+
```
|
46
|
+
--file, -f <s>: The file that will store the tags (default:
|
47
|
+
/etc/facter/facts.d/ec2_tags.json)
|
48
|
+
--all, -a: Collect all tags
|
49
|
+
--help, -h: Shows help
|
50
|
+
```
|
51
|
+
|
52
|
+
> **EXAMPLES**:
|
53
|
+
```
|
54
|
+
$ vscripts tags2facts
|
55
|
+
$ vscripts tags2facts --file /tmp/my_tags.json --all
|
56
|
+
```
|
57
|
+
|
58
|
+
|
59
|
+
## Contributing
|
60
|
+
|
61
|
+
1. Fork it ( https://github.com/vghn/vscripts/fork )
|
62
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
63
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
64
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
65
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
RAKE_ROOT = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH << File.join(RAKE_ROOT, 'tasks')
|
3
|
+
|
4
|
+
# Load all tasks
|
5
|
+
Dir['tasks/**/*.rake'].each { |task| load task }
|
6
|
+
|
7
|
+
# Rake
|
8
|
+
require 'rake/clean'
|
9
|
+
# Bundler
|
10
|
+
require "bundler/gem_tasks"
|
11
|
+
|
12
|
+
# RSpec
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
RSpec::Core::RakeTask.new
|
15
|
+
|
16
|
+
# Default task
|
17
|
+
task :default do
|
18
|
+
puts `rake -T`
|
19
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/vscripts
ADDED
data/lib/vscripts.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'vscripts/command'
|
2
|
+
require 'vscripts/command_line'
|
3
|
+
|
4
|
+
# Main VScripts module
|
5
|
+
module VScripts
|
6
|
+
# Gets the command name from command line and calls the right class.
|
7
|
+
def self.run(*args)
|
8
|
+
cli = CommandLine.new(*args)
|
9
|
+
command = VScripts::Commands.const_get(cli.command).new(*cli.extra)
|
10
|
+
command.execute
|
11
|
+
end
|
12
|
+
end # module VScripts
|
data/lib/vscripts/aws.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'vscripts/aws'
|
2
|
+
require 'vscripts/aws/metadata'
|
3
|
+
|
4
|
+
module VScripts
|
5
|
+
module AWS
|
6
|
+
# EC2 Class smells of :reek:UncommunicativeModuleName
|
7
|
+
# @ec2 smells of :reek:UncommunicativeVariableName
|
8
|
+
|
9
|
+
# AWS Elastic Compute Cloud
|
10
|
+
class EC2
|
11
|
+
include VScripts::AWS::Metadata
|
12
|
+
|
13
|
+
# Load AWS SDK for EC2
|
14
|
+
def initialize
|
15
|
+
@ec2 ||= ::AWS::EC2.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [AWS::EC2]
|
19
|
+
attr_reader :ec2
|
20
|
+
|
21
|
+
# Get instance object
|
22
|
+
def instance
|
23
|
+
check_instance
|
24
|
+
ec2.instances[instance_id]
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [AWS::EC2::ResourceTagCollection] Tags collection
|
28
|
+
def all_tags
|
29
|
+
instance.tags
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get a list of tags
|
33
|
+
def tags_without(list = [])
|
34
|
+
all = all_tags
|
35
|
+
list.each { |excluded| all.delete(excluded) }
|
36
|
+
all
|
37
|
+
end
|
38
|
+
|
39
|
+
# Looks for the value of the 'Name' tag for the given instance
|
40
|
+
def name
|
41
|
+
all_tags_hash['Name']
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return[AWS::EC2::InstanceCollection] Lists instances that have a
|
45
|
+
# 'Name' tag
|
46
|
+
def named_instances
|
47
|
+
ec2.instances.tagged('Name')
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return[Array] Lists instances that are not terminated
|
51
|
+
def functional_instances
|
52
|
+
named_instances.map do |named_instance|
|
53
|
+
named_instance if [:running, :shutting_down, :stopping, :stopped]
|
54
|
+
.include?(named_instance.status)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return[Array] The 'Name' tag value except the local instance
|
59
|
+
def similar_instances
|
60
|
+
check_instance
|
61
|
+
functional_instances.map do |functional_instance|
|
62
|
+
if functional_instance.id != instance_id
|
63
|
+
functional_instance.tags['Name']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end # class EC2
|
68
|
+
end # module Amazon
|
69
|
+
end # module VScripts
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module VScripts
|
5
|
+
module AWS
|
6
|
+
# This module contacts the AWS Metadata service to collect information
|
7
|
+
# about the EC2 instance.
|
8
|
+
module Metadata
|
9
|
+
# @return [String] Metadata URL
|
10
|
+
def metadata_url
|
11
|
+
'http://instance-data/latest/meta-data'
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [String] Get availability zone from metadata
|
15
|
+
def zone
|
16
|
+
open("#{metadata_url}/placement/availability-zone")
|
17
|
+
.read
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] Get the region from the zone
|
21
|
+
def region
|
22
|
+
zone[/^(.*[\d])[a-z]$/, 1]
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] Get instance's ID from metadata
|
26
|
+
def instance_id
|
27
|
+
open("#{metadata_url}/instance-id").read
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] Get instance's public hostname from metadata
|
31
|
+
def public_hostname
|
32
|
+
open("#{metadata_url}/public-hostname").read
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Boolean] Check connection to service
|
36
|
+
def ec2_instance?
|
37
|
+
Net::HTTP.get_response(URI.parse(metadata_url)) && true
|
38
|
+
rescue
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
# Fail if the current instance is not an EC2 instance
|
43
|
+
def check_instance
|
44
|
+
unless ec2_instance?
|
45
|
+
abort 'FATAL: NOT an EC2 instance or could not connect to Metadata'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end # module Metadata
|
49
|
+
end # module AWS
|
50
|
+
end # module VScripts
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'vscripts/commands/tags2facts'
|
2
|
+
|
3
|
+
module VScripts
|
4
|
+
# Main Command class
|
5
|
+
class Command
|
6
|
+
# Lists the available commands
|
7
|
+
# @return [Array]
|
8
|
+
def self.list
|
9
|
+
VScripts::Commands.constants.select do |cls|
|
10
|
+
VScripts::Commands.const_get(cls).is_a? Class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end # class Command
|
14
|
+
end # module VScripts
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'vscripts/command'
|
3
|
+
|
4
|
+
module VScripts
|
5
|
+
# Global Command Line
|
6
|
+
class CommandLine
|
7
|
+
# @return [Hash] Global command line arguments
|
8
|
+
attr_reader :global
|
9
|
+
# @return [String] Command name
|
10
|
+
attr_reader :command
|
11
|
+
# @return [Array] Extra arguments passed to the command
|
12
|
+
attr_reader :extra
|
13
|
+
|
14
|
+
# Build command line arguments
|
15
|
+
def initialize(*args)
|
16
|
+
@global ||= parse(*args)
|
17
|
+
@command ||= check_command(*args)
|
18
|
+
@extra ||= rest(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Specifies command line options
|
22
|
+
# This method smells of :reek:NestedIterators but ignores them
|
23
|
+
# This method smells of :reek:TooManyStatements but ignores them
|
24
|
+
def parser # rubocop:disable MethodLength
|
25
|
+
available = Command.list
|
26
|
+
Trollop::Parser.new do
|
27
|
+
version VScripts::VERSION_C
|
28
|
+
banner <<-EOS
|
29
|
+
VScripts automation daemon.
|
30
|
+
|
31
|
+
Available commands:
|
32
|
+
#{available.map { |cmd| cmd.to_s.downcase }}
|
33
|
+
|
34
|
+
Usage:
|
35
|
+
vscripts GLOBAL-OPTIONS COMMAND OPTIONS
|
36
|
+
|
37
|
+
For help on an individual command:
|
38
|
+
vscripts COMMAND --help
|
39
|
+
|
40
|
+
Global Options:
|
41
|
+
EOS
|
42
|
+
stop_on available
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parses command line arguments
|
47
|
+
def parse(*args)
|
48
|
+
Trollop.with_standard_exception_handling parser do
|
49
|
+
fail Trollop::HelpNeeded if args.empty?
|
50
|
+
parser.parse args
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Ensure command is available
|
55
|
+
# @return [String] Command name
|
56
|
+
def check_command(args)
|
57
|
+
command_cli = args.shift
|
58
|
+
command_cls = command_cli.capitalize.to_sym
|
59
|
+
if command_cli && Command.list.include?(command_cls)
|
60
|
+
return command_cls
|
61
|
+
else
|
62
|
+
puts "Error: Unknown subcommand '#{command_cli}'\nTry --help for help."
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Array] The rest of the arguments
|
68
|
+
def rest(args)
|
69
|
+
args
|
70
|
+
end
|
71
|
+
end # class CommandLine
|
72
|
+
end # module VScripts
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'vscripts/aws/ec2'
|
3
|
+
require 'vscripts/util/local_system'
|
4
|
+
|
5
|
+
module VScripts
|
6
|
+
# Commands module
|
7
|
+
module Commands
|
8
|
+
# @ec2 smells of :reek:UncommunicativeVariableName
|
9
|
+
|
10
|
+
# Tags2Facts Class
|
11
|
+
class Tags2facts
|
12
|
+
include VScripts::Util::LocalSystem
|
13
|
+
|
14
|
+
# HELP
|
15
|
+
USAGE = <<-EOS
|
16
|
+
|
17
|
+
This command can only be run on an AWS EC2 instance. It looks for all tags
|
18
|
+
associated with it and dumps them in a JSON file. By default this file is
|
19
|
+
`/etc/facter/facts.d/ec2_tags.json`. It can be overridden with the
|
20
|
+
***`--file`*** argument.
|
21
|
+
|
22
|
+
The `Name` and `Domain` tags are excluded by default because this command is
|
23
|
+
intended to add Facter facts and these 2 already exist in Facter. This
|
24
|
+
behaviour can be overridden by adding `[-a|--all]` command line option.
|
25
|
+
|
26
|
+
Usage:
|
27
|
+
$ vscripts tags2facts [options]
|
28
|
+
|
29
|
+
Options:
|
30
|
+
EOS
|
31
|
+
|
32
|
+
# @return [Hash] Command specific arguments
|
33
|
+
attr_reader :cli
|
34
|
+
# @return [AWS::EC2] EC2 SDK
|
35
|
+
attr_reader :ec2
|
36
|
+
|
37
|
+
def initialize(*args)
|
38
|
+
@cli ||= parse(*args)
|
39
|
+
@ec2 ||= VScripts::AWS::EC2.new
|
40
|
+
end
|
41
|
+
|
42
|
+
# Specifies command line options
|
43
|
+
def parser
|
44
|
+
Trollop::Parser.new do
|
45
|
+
banner USAGE
|
46
|
+
opt :file, 'The file that will store the tags',
|
47
|
+
type: :string, default: '/etc/facter/facts.d/ec2_tags.json'
|
48
|
+
opt :all, 'Collect all tags'
|
49
|
+
stop_on_unknown
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Parses command line arguments
|
54
|
+
def parse(*args)
|
55
|
+
Trollop.with_standard_exception_handling parser do
|
56
|
+
parser.parse args
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Array] A list of tags to be excluded
|
61
|
+
def exclude_list
|
62
|
+
cli.all ? [] : %w(Name Domain)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Hash] Tags table
|
66
|
+
def tags_hash
|
67
|
+
ec2.tags_without(exclude_list).to_h
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [JSON] Formatted JSON
|
71
|
+
def tags_json
|
72
|
+
JSON.pretty_generate(tags_hash.to_h)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Writes the formatted JSON to a file
|
76
|
+
def execute
|
77
|
+
file = cli.file
|
78
|
+
puts "Writing tags to \"#{file}\""
|
79
|
+
ensure_file_content(file, tags_json)
|
80
|
+
puts 'Done.'
|
81
|
+
end
|
82
|
+
end # class Tags2facts
|
83
|
+
end # module Commands
|
84
|
+
end # module VScripts
|