snow_sync 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 506885e6696500d58f9d15a51fe258553dc6fe56
4
+ data.tar.gz: f407806b0f76dd8242dfda26477703343263443d
5
+ SHA512:
6
+ metadata.gz: 3fb70baf285cd176fd06857e862d2b9325f9f6d284efb58b984424f3bb737031ac98662da0e2d148c4cde315f3aa9282592c9c46d6ecb18fb1f2ae95c331cda2
7
+ data.tar.gz: 67d6ba7bf8d7a8fe6ba6250e3ae8c6c98cc3d83a164cee84c4f8171ce72b2743bbb1dfe9f9cb27e3d6fa2a8c8fc4c42f52c03f222e1e010557fadccdf2331955
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Andy Wallace
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # SnowSync
2
+
3
+ SnowSync is a file sync utility tool and API which provides a bridge for off platform ServiceNow development using an IDE or text editor locally.
4
+
5
+ SnowSync syncronizes configured fields (scripts) for a ServiceNow instance locally, then watches for file changes and syncs back changes to the corresponding record.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'snow_sync'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install snow_sync
22
+
23
+ ## Setup & Usage
24
+
25
+ Coming soon...
26
+
27
+ ## License
28
+
29
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
30
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "snow_sync"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,42 @@
1
+ require "logger"
2
+ require "./sync_util.rb"
3
+
4
+ @util = SnowSync::SyncUtil.new
5
+
6
+ yield_options = {
7
+
8
+ object: ::Logger.new(STDERR),
9
+
10
+ start: proc do |logger|
11
+ logger.level = Logger::INFO
12
+ @util.start_sync
13
+ end,
14
+
15
+ stop: proc do |logger|
16
+ logger.info "Guard::Yield - Done!"
17
+ end,
18
+
19
+ run_on_modifications: proc do |log, _, files|
20
+ log.info "!!: #{files * ','}"
21
+ @util.push_modifications(files)
22
+ end,
23
+
24
+ run_on_additions: proc do |log, _, files|
25
+ log.info "++: #{files * ','}"
26
+ end,
27
+
28
+ run_on_removals: proc do |log, _, files|
29
+ log.warn "xx: #{files * ','}"
30
+ end,
31
+
32
+ }
33
+
34
+ # method initializes the watcher
35
+ def guard_watch(yield_options)
36
+ guard :yield, yield_options do
37
+ watch(/^sync\//)
38
+ end
39
+ end
40
+
41
+ # called when guard starts
42
+ guard_watch(yield_options)
@@ -0,0 +1,13 @@
1
+ ---
2
+ base_url:
3
+
4
+ creds:
5
+ user:
6
+ pass:
7
+
8
+ table_map:
9
+ script_include:
10
+ name:
11
+ table:
12
+ sysid:
13
+ field:
@@ -0,0 +1,130 @@
1
+ module SnowSync
2
+
3
+ class SyncUtil
4
+
5
+ require "base64"
6
+ require "facets"
7
+ require "fileutils"
8
+ require "json"
9
+ require 'rest-client'
10
+ require "yaml"
11
+
12
+ attr_accessor :configs, :logger
13
+
14
+ def initialize(opts = nil)
15
+ opts.nil? ? c = "configs.yml" : c = "test_configs.yml"
16
+ @configs = YAML::load_file(c)
17
+ @logger = Logger.new(STDERR)
18
+ end
19
+
20
+ def create_directory(name, &block)
21
+ yield block if block_given?
22
+ unless File.directory?(name)
23
+ FileUtils.mkdir_p(name)
24
+ @logger.info "++: #{name}"
25
+ end
26
+ end
27
+
28
+ def create_file(name, json, &block)
29
+ yield if block_given?
30
+ File.open("#{name}.js", "w") do |f|
31
+ f.write(json)
32
+ @logger.info "->: #{name}" + ".js"
33
+ end
34
+ end
35
+
36
+ def check_required_configs
37
+ no_credentials = @configs["creds"].values.any? do |e|
38
+ e.nil?
39
+ end
40
+ keys = @configs["table_map"].keys
41
+ keys.each do |key|
42
+ no_table_map = @configs["table_map"][key].values.any? do |e|
43
+ e.nil?
44
+ end
45
+ if no_credentials or no_table_map
46
+ raise "EXCEPTION: Required configs missing in configs.yml. " \
47
+ "Please check your credentials and tables to sync."
48
+ else
49
+ return @configs
50
+ end
51
+ end
52
+ end
53
+
54
+ def setup_sync_directories
55
+ @configs["table_map"].each do |key, value|
56
+ directory_name = "sync"
57
+ create_directory(directory_name)
58
+ path = proc { FileUtils.cd(directory_name) }
59
+ sub_directory_name = key
60
+ create_directory(sub_directory_name, &path)
61
+ begin
62
+ user = @configs["creds"]["user"]
63
+ pass = @configs["creds"]["pass"]
64
+ response = RestClient.get(
65
+ "#{@configs['base_url']}#{value["table"]}?sysparm_query=sys_id%3D" +
66
+ "#{value["sysid"]}%5Ename%3D#{value["name"]}",
67
+ {:authorization => "#{"Basic " + Base64.strict_encode64("#{user}:#{pass}")}",
68
+ :accept => "application/json"})
69
+ path = proc { FileUtils.cd(sub_directory_name) }
70
+ @configs[value["table"] + "_response"] = JSON.parse(response)["result"][0]
71
+ json = JSON.parse(response)["result"][0][value["field"]]
72
+ name = value["name"].snakecase
73
+ create_file(name, json, &path)
74
+ FileUtils.cd("../..")
75
+ rescue => e
76
+ @logger.error "ERROR: #{e}"
77
+ end
78
+ end
79
+ end
80
+
81
+ def classify(file)
82
+ file = file.split("/").last.split(".").first.camelcase
83
+ file[0] = file[0].capitalize
84
+ return file
85
+ end
86
+
87
+ def table_lookup(file)
88
+ @configs["table_map"].select do |key, value|
89
+ if value["name"].eql?(classify(file))
90
+ return value
91
+ end
92
+ end
93
+ end
94
+
95
+ def merge_update(file, table_hash)
96
+ FileUtils.cd(file.split("/")[0..1].join("/"))
97
+ script_body = File.open(file.split("/").last).read
98
+ @configs[table_hash["table"] + "_response"] = script_body
99
+ FileUtils.cd("../..")
100
+ end
101
+
102
+ def start_sync
103
+ check_required_configs
104
+ setup_sync_directories
105
+ end
106
+
107
+ def push_modifications(files)
108
+ files.each do |file|
109
+ file.downcase!
110
+ table_hash = table_lookup(file)
111
+ merge_update(file, table_hash)
112
+ begin
113
+ user = @configs["creds"]["user"]
114
+ pass = @configs["creds"]["pass"]
115
+ request_body_map = {
116
+ table_hash["field"].to_sym => @configs[table_hash["table"] + "_response"]
117
+ }
118
+ response = RestClient.patch("#{@configs['base_url']}#{table_hash["table"]}/#{table_hash["sysid"]}",
119
+ request_body_map.to_json,
120
+ {:authorization => "#{"Basic " + Base64.strict_encode64("#{user}:#{pass}")}",
121
+ :content_type => "application/json", :accept => "application/json"})
122
+ rescue => e
123
+ @logger.error "ERROR: #{e}"
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ end
@@ -0,0 +1,3 @@
1
+ module SnowSync
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,108 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ require "byebug"
21
+ require "facets"
22
+ require "fileutils"
23
+ require "json"
24
+ require_relative "../lib/snow_sync/sync_util.rb"
25
+ # rspec-expectations config goes here. You can use an alternate
26
+ # assertion/expectation library such as wrong or the stdlib/minitest
27
+ # assertions if you prefer.
28
+ config.expect_with :rspec do |expectations|
29
+ # This option will default to `true` in RSpec 4. It makes the `description`
30
+ # and `failure_message` of custom matchers include text for helper methods
31
+ # defined using `chain`, e.g.:
32
+ # be_bigger_than(2).and_smaller_than(4).description
33
+ # # => "be bigger than 2 and smaller than 4"
34
+ # ...rather than:
35
+ # # => "be bigger than 2"
36
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
37
+ end
38
+
39
+ # rspec-mocks config goes here. You can use an alternate test double
40
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
41
+ config.mock_with :rspec do |mocks|
42
+ # Prevents you from mocking or stubbing a method that does not exist on
43
+ # a real object. This is generally recommended, and will default to
44
+ # `true` in RSpec 4.
45
+ mocks.verify_partial_doubles = true
46
+ end
47
+
48
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
49
+ # have no way to turn it off -- the option exists only for backwards
50
+ # compatibility in RSpec 3). It causes shared context metadata to be
51
+ # inherited by the metadata hash of host groups and examples, rather than
52
+ # triggering implicit auto-inclusion in groups with matching metadata.
53
+ config.shared_context_metadata_behavior = :apply_to_host_groups
54
+
55
+ # The settings below are suggested to provide a good initial experience
56
+ # with RSpec, but feel free to customize to your heart's content.
57
+ =begin
58
+ # This allows you to limit a spec run to individual examples or groups
59
+ # you care about by tagging them with `:focus` metadata. When nothing
60
+ # is tagged with `:focus`, all examples get run. RSpec also provides
61
+ # aliases for `it`, `describe`, and `context` that include `:focus`
62
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
63
+ config.filter_run_when_matching :focus
64
+
65
+ # Allows RSpec to persist some state between runs in order to support
66
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
67
+ # you configure your source control system to ignore this file.
68
+ config.example_status_persistence_file_path = "spec/examples.txt"
69
+
70
+ # Limits the available syntax to the non-monkey patched syntax that is
71
+ # recommended. For more details, see:
72
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
73
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
74
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
75
+ config.disable_monkey_patching!
76
+
77
+ # This setting enables warnings. It's recommended, but in some cases may
78
+ # be too noisy due to issues in dependencies.
79
+ config.warnings = true
80
+
81
+ # Many RSpec users commonly either run the entire suite or an individual
82
+ # file, and it's useful to allow more verbose output when running an
83
+ # individual spec file.
84
+ if config.files_to_run.one?
85
+ # Use the documentation formatter for detailed output,
86
+ # unless a formatter has already been configured
87
+ # (e.g. via a command-line flag).
88
+ config.default_formatter = 'doc'
89
+ end
90
+
91
+ # Print the 10 slowest examples and example groups at the
92
+ # end of the spec run, to help surface which specs are running
93
+ # particularly slow.
94
+ config.profile_examples = 10
95
+
96
+ # Run specs in random order to surface order dependencies. If you find an
97
+ # order dependency and want to debug it, you can fix the order by providing
98
+ # the seed, which is printed after each run.
99
+ # --seed 1234
100
+ config.order = :random
101
+
102
+ # Seed global randomization in this process using the `--seed` CLI option.
103
+ # Setting this allows you to use `--seed` to deterministically reproduce
104
+ # test failures related to randomization by passing the same `--seed` value
105
+ # as the one that triggered the failure.
106
+ Kernel.srand config.seed
107
+ =end
108
+ end
@@ -0,0 +1,202 @@
1
+ require "spec_helper"
2
+
3
+ def setup_test_config
4
+ util.configs["base_url"] = "<base url>"
5
+ util.configs["creds"]["user"] = "<username>"
6
+ util.configs["creds"]["pass"] = "<password>"
7
+ util.configs["table_map"]["script_include"]["name"] = "<js class or script name>"
8
+ util.configs["table_map"]["script_include"]["table"] = "<table>"
9
+ util.configs["table_map"]["script_include"]["sysid"] = "<sys id>"
10
+ util.configs["table_map"]["script_include"]["field"] = "<field>"
11
+ end
12
+
13
+ def setup_test_directory
14
+ FileUtils.mkdir_p("sync")
15
+ FileUtils.mkdir_p("sync/test_sub_dir")
16
+ end
17
+
18
+ ## --> unit tests
19
+ describe "utility object" do
20
+
21
+ let! :util do
22
+ SnowSync::SyncUtil.new(opts = "test")
23
+ end
24
+
25
+ it "should instantiate a utility object" do
26
+ expect(util.is_a?(Object)).to eq true
27
+ end
28
+
29
+ it "should encapsulate a configs hash" do
30
+ expect(util.configs.is_a?(Hash)).to eq true
31
+ end
32
+
33
+ it "should encapsulate a logger object" do
34
+ expect(util.logger.is_a?(Object)).to eq true
35
+ end
36
+
37
+ end
38
+
39
+ describe "create_directory" do
40
+
41
+ let! :util do
42
+ SnowSync::SyncUtil.new(opts = "test")
43
+ end
44
+
45
+ let! :created_time do
46
+ util.create_directory("sync")
47
+ return File.ctime("sync")
48
+ end
49
+
50
+ it "should create a directory" do
51
+ dir = `ls`.split("\n")
52
+ expect(dir.include?("sync")).to eq true
53
+ end
54
+
55
+ it "should not create directory" do
56
+ util.create_directory("sync")
57
+ check_created_time = File.ctime("sync")
58
+ expect(created_time).to eq check_created_time
59
+ end
60
+
61
+ end
62
+
63
+ describe "create_file" do
64
+
65
+ let! :util do
66
+ SnowSync::SyncUtil.new(opts = "test")
67
+ end
68
+
69
+ it "should create a file" do
70
+ setup_test_directory
71
+ json = { "property" => "value" }
72
+ name = "TestClass".snakecase
73
+ path = proc do
74
+ FileUtils.cd("sync/test_sub_dir")
75
+ end
76
+ util.create_file(name, json, &path)
77
+ expect(File.exists?("test_class.js")).to eq true
78
+ FileUtils.cd("../..")
79
+ FileUtils.rm_rf("sync")
80
+ end
81
+
82
+ end
83
+
84
+ describe "check_required_configs" do
85
+
86
+ let :util do
87
+ SnowSync::SyncUtil.new(opts = "test")
88
+ end
89
+
90
+ it "should raise an exception when there are no credentials" do
91
+ #user, no password
92
+ util.configs["creds"]["user"] = "test.user"
93
+ expect{util.check_required_configs}.to raise_error(/Please check your credentials and tables to sync/)
94
+ end
95
+
96
+ it "should raise an exception when there are no tables mapped" do
97
+ #table, no attributes
98
+ util.configs["table_map"]["table"] = "test_table"
99
+ expect{util.check_required_configs}.to raise_error(/Please check your credentials and tables to sync/)
100
+ end
101
+
102
+ end
103
+
104
+ describe "classify" do
105
+
106
+ let :util do
107
+ SnowSync::SyncUtil.new(opts = "test")
108
+ end
109
+
110
+ it "should convert snake_case string to CamelCase" do
111
+ js_file_path = "sync/script_include/test_class.js"
112
+ cc = util.classify(js_file_path)
113
+ expect(cc).to eq "TestClass"
114
+ end
115
+
116
+ end
117
+
118
+ describe "table_lookup" do
119
+
120
+ let :util do
121
+ SnowSync::SyncUtil.new(opts = "test")
122
+ end
123
+
124
+ it "should return configured SN table" do
125
+ setup_test_config
126
+ table_map = util.table_lookup("sync/script_include/test_class.rb")
127
+ expect(table_map.keys).to eq ["name", "table", "sysid", "field"]
128
+ expect(table_map["table"]).to eq "sys_script_include"
129
+ end
130
+
131
+ end
132
+
133
+ describe "merge_update" do
134
+
135
+ let! :util do
136
+ SnowSync::SyncUtil.new(opts = "test")
137
+ end
138
+
139
+ #merge_update
140
+ it "should merge updated script with the configs object" do
141
+ setup_test_directory
142
+ setup_test_config
143
+ json = { "property" => "value - with update" }
144
+ name = "TestClass".snakecase
145
+ path = proc do
146
+ FileUtils.cd("sync/test_sub_dir")
147
+ end
148
+ util.create_file(name, json, &path)
149
+ FileUtils.cd("../..")
150
+ file = "sync/test_sub_dir/test_class.js"
151
+ table_map = util.table_lookup(file)
152
+ util.merge_update(file, table_map)
153
+ expect(util.configs["sys_script_include_response"] != nil).to eq true
154
+ end
155
+
156
+ end
157
+
158
+ ## --> itegration tests
159
+ describe "setup_sync_directories" do
160
+
161
+ let! :util do
162
+ SnowSync::SyncUtil.new(opts = "test")
163
+ end
164
+
165
+ it "should setup and synchronize field from the SN instance" do
166
+ setup_test_config
167
+ util.setup_sync_directories
168
+ file = File.open("sync/script_include/test_class.js")
169
+ expect(file.is_a?(Object)).to eq true
170
+ FileUtils.rm_rf("sync")
171
+ end
172
+
173
+ end
174
+
175
+ describe "push_modifications" do
176
+
177
+ let! :util do
178
+ SnowSync::SyncUtil.new(opts = "test")
179
+ end
180
+
181
+ it "should push modifications to a configured instance" do
182
+ setup_test_config
183
+ util.setup_sync_directories
184
+ file = File.open("sync/script_include/test_class.js", "r+")
185
+ lines = file.readlines
186
+ file.close
187
+ lines[0] = "// test comment -\n"
188
+ newfile = File.new("sync/script_include/test_class.js", "w")
189
+ lines.each do |line|
190
+ newfile.write(line)
191
+ end
192
+ newfile.close
193
+ util.push_modifications(["sync/script_include/test_class.js"])
194
+ util.setup_sync_directories
195
+ file = File.open("sync/script_include/test_class.js", "r+")
196
+ lines = file.readlines
197
+ file.close
198
+ expect(lines[0]).to eq "// test comment -\n"
199
+ FileUtils.rm_rf("sync")
200
+ end
201
+
202
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snow_sync
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andy Wallace
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: facets
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-yield
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.8'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.8.3
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '1.8'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.8.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: libnotify
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.9.1
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 0.9.1
103
+ - !ruby/object:Gem::Dependency
104
+ name: rake
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '10.0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '10.0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rest-client
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '2.0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '2.0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rspec
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '3.0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '3.0'
145
+ description: SnowSync syncronizes configured fields (scripts) for a ServiceNow instance
146
+ locally, then watches for file changes and syncs back script changes to the corresponding
147
+ record.
148
+ email: sailingthetechseas@gmail.com
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - LICENSE.txt
154
+ - README.md
155
+ - Rakefile
156
+ - bin/console
157
+ - bin/setup
158
+ - lib/snow_sync/Guardfile
159
+ - lib/snow_sync/configs.yml
160
+ - lib/snow_sync/sync_util.rb
161
+ - lib/snow_sync/version.rb
162
+ - spec/spec_helper.rb
163
+ - spec/sync_util_spec.rb
164
+ homepage: https://rubygems.org/gems/snow_sync
165
+ licenses:
166
+ - MIT
167
+ metadata: {}
168
+ post_install_message:
169
+ rdoc_options: []
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 2.6.8
185
+ signing_key:
186
+ specification_version: 4
187
+ summary: SnowSync is a file sync utility tool and API which provides a bridge for
188
+ off platform ServiceNow development using an IDE or text editor locally.
189
+ test_files: []