singer-heroku 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a4f7cd180234a6480890663a4434f6d31225dd6e
4
+ data.tar.gz: c8079832fb851026ae94bad62f74db9d2421cf2b
5
+ SHA512:
6
+ metadata.gz: 92b3a846aa6ef35cacd35d49cb9e66c25ad4d4de9edf3fffab634f42c677159e17a7bf325c7fd5539644bbcef520da478c05fd80006f51464fe42d6e3320571a
7
+ data.tar.gz: 5898760849d0d1ada74a8ceb3d423cd77b34e8d35f16621e06d9abd5e8689c25ee733fccb24fa210ade659bcff2195d5bc4f5648f9f889b9324695d054f07f2f
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 follain
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.
@@ -0,0 +1,46 @@
1
+ singer-heroku
2
+ =============
3
+
4
+ A collection of utilities to facilitate running [singer.io](http://singer.io)
5
+ taps and targets on Heroku
6
+
7
+ ## Installation
8
+
9
+ gem install singer-heroku
10
+
11
+
12
+ ## generate-config
13
+
14
+ Reads from `#{KEY}_CONFIG_*` environment variables and generates json to
15
+ stdout.
16
+
17
+ Given the following ENV:
18
+
19
+ TEST_CONFIG_first_name=joe
20
+ TEST_CONFIG_last_name=lind
21
+
22
+ generate-config -k TEST
23
+ {"first_name":"joe","last_name":"lind"}
24
+
25
+ ## read-state
26
+
27
+ Reads JSON `data` from `singer_states` table in `DATABASE_URL` where key is
28
+ `#{KEY}`, passed in args.
29
+
30
+ > read-state -kTEST
31
+ {"high_water_mark":4}
32
+
33
+
34
+ ## write-state
35
+
36
+ Reads jsonl from stdin and writes to database specified in DATABASE_URL
37
+
38
+ > cat states.json
39
+ { "high_water_mark": 1 }
40
+ { "high_water_mark": 2 }
41
+ { "high_water_mark": 3 }
42
+ { "high_water_mark": 4 }
43
+
44
+ > cat states.json | write-state -kTEST
45
+ > read-state -kTEST
46
+ {"high_water_mark":4}
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler'
4
+ Bundler.require
5
+
6
+ require 'optparse'
7
+ require_relative '../lib/generate_config'
8
+
9
+ config = nil
10
+
11
+ parser = OptionParser.new do |opts|
12
+ opts.banner = "Usage: #{$0} [options]"
13
+ opts.on('-k', '--key key', 'Config key prefix') do |key|
14
+ config = GenerateConfig.new(ENV.to_h.dup, key)
15
+ end
16
+
17
+ opts.on_tail('-h', '--help', 'Displays help') do
18
+ puts opts
19
+ exit
20
+ end
21
+ end
22
+
23
+ parser.parse!
24
+
25
+ unless config
26
+ puts parser
27
+ exit 1
28
+ end
29
+
30
+ puts config.to_json
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler'
5
+ Bundler.require
6
+
7
+ require 'optparse'
8
+ require_relative '../lib/database'
9
+ require_relative '../lib/read_state'
10
+ require 'dotenv/load'
11
+ require 'logger'
12
+
13
+ read_state = nil
14
+ database = Database.new(ENV.fetch('DATABASE_URL'))
15
+
16
+ parser = OptionParser.new do |opts|
17
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
18
+ opts.on('-k', '--key key', 'Config key prefix') do |key|
19
+ read_state = ReadState.new(key, database)
20
+ end
21
+
22
+ opts.on_tail('-v', '--verbose', 'Enable verbose logging') do
23
+ database.logger = Logger.new($stderr)
24
+ end
25
+
26
+ opts.on_tail('-h', '--help', 'Displays help') do
27
+ puts opts
28
+ exit
29
+ end
30
+ end
31
+
32
+ parser.parse!
33
+
34
+ unless read_state
35
+ puts parser
36
+ exit 1
37
+ end
38
+
39
+ puts JSON.generate(read_state.perform)
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler'
5
+ Bundler.require
6
+
7
+ require 'optparse'
8
+ require 'logger'
9
+ require_relative '../lib/database'
10
+ require_relative '../lib/write_state'
11
+ require 'dotenv/load'
12
+
13
+ write_state = nil
14
+ database = Database.new(ENV.fetch('DATABASE_URL'))
15
+
16
+ parser = OptionParser.new do |opts|
17
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
18
+ opts.on('-k', '--key key', 'Config key prefix') do |key|
19
+ write_state = WriteState.new(key, database)
20
+ end
21
+
22
+ opts.on_tail('-v', '--verbose', 'Enable verbose logging') do
23
+ database.logger = Logger.new($stderr)
24
+ end
25
+
26
+ opts.on_tail('-h', '--help', 'Displays help') do
27
+ puts opts
28
+ exit
29
+ end
30
+ end
31
+
32
+ parser.parse!
33
+
34
+ unless write_state
35
+ puts parser
36
+ exit 1
37
+ end
38
+
39
+ while STDIN.gets
40
+ state = $LAST_READ_LINE.chomp
41
+ write_state.perform JSON.parse(state)
42
+ end
@@ -0,0 +1,20 @@
1
+
2
+ # frozen_string_literal: true
3
+
4
+ require 'sequel'
5
+
6
+ Database = Struct.new(:url) do
7
+ def db
8
+ @db ||= Sequel.connect(url).tap do |db|
9
+ db.extension :pg_json
10
+ end
11
+ end
12
+
13
+ def states
14
+ db[:singer_states]
15
+ end
16
+
17
+ def logger=(logger)
18
+ db.loggers = [logger]
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ GenerateConfig = Struct.new(:env, :key) do
6
+ def key_pattern
7
+ /^#{key}_CONFIG_(.+)/
8
+ end
9
+
10
+ def to_json
11
+ JSON.generate(values)
12
+ end
13
+
14
+ def values
15
+ Hash[
16
+ env.keys.grep(key_pattern).map do |key|
17
+ [
18
+ key.match(key_pattern)[1],
19
+ cast_if_needed(env[key])
20
+ ]
21
+ end
22
+ ]
23
+ end
24
+
25
+ private
26
+
27
+ def cast_if_needed(value)
28
+ return value.to_i if value.to_i.to_s == value
29
+ return value.to_f if value.to_f.to_s == value
30
+
31
+ value
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel'
4
+
5
+ module SingerHeroku
6
+ # Rake tasks for migrating development database
7
+ class RakeTasks
8
+ include Rake::DSL if defined? Rake::DSL
9
+
10
+ # rubocop:disable Rails/Output
11
+ def install_tasks
12
+ namespace :singer_heroku do
13
+ desc 'Run migrations'
14
+ task :migrate, [:version] do |_t, args|
15
+ Sequel.extension :migration
16
+ db = Sequel.connect(ENV.fetch('DATABASE_URL'))
17
+ version = args[:version]
18
+ puts "Migrating to #{version || 'latest'}"
19
+ version = version&.to_i
20
+ Sequel::Migrator.run(db, 'db/migrations', target: version)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ SingerHeroku::RakeTasks.new.install_tasks
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ ReadState = Struct.new(:key, :database) do
4
+ def perform
5
+ record = database.states.where(key: key).first
6
+ return record[:data] if record
7
+ {}
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SingerHeroku
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ WriteState = Struct.new(:key, :database) do
4
+ def perform(value)
5
+ insert.call key: key, data: Sequel.pg_json(value)
6
+ end
7
+
8
+ private
9
+
10
+ def insert
11
+ @insert ||= database
12
+ .states
13
+ .insert_conflict(
14
+ target: :key, update: { data: Sequel[:excluded][:data] }
15
+ )
16
+ .prepare(:insert, :insert_state, key: :$key, data: :$data)
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: singer-heroku
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joe Lind
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.21'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.21'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sequel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.49'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.49'
55
+ description: " Creates config files from ENV; Read/writes state from postgres database\n"
56
+ email: joelind@gmail.com
57
+ executables:
58
+ - generate-config
59
+ - read-state
60
+ - write-state
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - LICENSE
65
+ - README.md
66
+ - bin/generate-config
67
+ - bin/read-state
68
+ - bin/write-state
69
+ - lib/database.rb
70
+ - lib/generate_config.rb
71
+ - lib/rake_tasks.rb
72
+ - lib/read_state.rb
73
+ - lib/singer_heroku/version.rb
74
+ - lib/write_state.rb
75
+ homepage: https://github.com/Follain/singer-heroku
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.5.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Singer.io utilities for executing on Heroku
99
+ test_files: []