gtm-cli 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/gtm-cli/.gitignore +1 -0
- data/gtm-cli/.rspec +2 -0
- data/gtm-cli/Gemfile +7 -0
- data/gtm-cli/Gemfile.lock +152 -0
- data/gtm-cli/README.md +61 -0
- data/gtm-cli/bin/gtm +36 -0
- data/gtm-cli/gtm-cli.gemspec +28 -0
- data/gtm-cli/lib/gtm/bootstrap.rb +42 -0
- data/gtm-cli/lib/gtm/client.rb +58 -0
- data/gtm-cli/lib/gtm/pull.rb +95 -0
- data/gtm-cli/lib/gtm/push.rb +38 -0
- data/gtm-cli/lib/gtm/version.rb +3 -0
- data/gtm-cli/lib/gtm.rb +11 -0
- data/gtm-cli/spec/gtm/bootstrap_spec.rb +65 -0
- data/gtm-cli/spec/spec_helper.rb +92 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ee3b2ad847773b21ac9fcbbb6826db803351710
|
4
|
+
data.tar.gz: 5aed11f610b6d19d45b9c419784644ec56b8074a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca8d44c2660e5b13ee62d1f122bfa3976f91cd5b19350a4aa984f7aec7d9949127d29d1ff302efb5a45ca500f53d848b3d4e0374f2905ac55799634e0658b66d
|
7
|
+
data.tar.gz: a2f32e2f07592b825eb78d7011ad1f5479ab3d6f151cf7c6034a6a1ddfff1a05d7bd829afe0d91261f28fc80f14b71bf3162393758db847cfc51955cdb531a16
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.idea
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gtm
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.2-head
|
data/gtm-cli/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
client_secrets.json
|
data/gtm-cli/.rspec
ADDED
data/gtm-cli/Gemfile
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gtm (0.0.9)
|
5
|
+
activesupport (~> 4.1)
|
6
|
+
commander (~> 4.2)
|
7
|
+
google-api-client (~> 0.8)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (4.2.1)
|
13
|
+
i18n (~> 0.7)
|
14
|
+
json (~> 1.7, >= 1.7.7)
|
15
|
+
minitest (~> 5.1)
|
16
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
17
|
+
tzinfo (~> 1.1)
|
18
|
+
addressable (2.3.8)
|
19
|
+
ast (2.0.0)
|
20
|
+
astrolabe (1.3.0)
|
21
|
+
parser (>= 2.2.0.pre.3, < 3.0)
|
22
|
+
autoparse (0.3.3)
|
23
|
+
addressable (>= 2.3.1)
|
24
|
+
extlib (>= 0.9.15)
|
25
|
+
multi_json (>= 1.0.0)
|
26
|
+
celluloid (0.16.0)
|
27
|
+
timers (~> 4.0.0)
|
28
|
+
coderay (1.1.0)
|
29
|
+
commander (4.3.4)
|
30
|
+
highline (~> 1.7.2)
|
31
|
+
diff-lcs (1.2.5)
|
32
|
+
extlib (0.9.16)
|
33
|
+
faraday (0.9.1)
|
34
|
+
multipart-post (>= 1.2, < 3)
|
35
|
+
ffi (1.9.8)
|
36
|
+
formatador (0.2.5)
|
37
|
+
google-api-client (0.8.6)
|
38
|
+
activesupport (>= 3.2)
|
39
|
+
addressable (~> 2.3)
|
40
|
+
autoparse (~> 0.3)
|
41
|
+
extlib (~> 0.9)
|
42
|
+
faraday (~> 0.9)
|
43
|
+
googleauth (~> 0.3)
|
44
|
+
launchy (~> 2.4)
|
45
|
+
multi_json (~> 1.10)
|
46
|
+
retriable (~> 1.4)
|
47
|
+
signet (~> 0.6)
|
48
|
+
googleauth (0.4.1)
|
49
|
+
faraday (~> 0.9)
|
50
|
+
jwt (~> 1.4)
|
51
|
+
logging (~> 2.0)
|
52
|
+
memoist (~> 0.12)
|
53
|
+
multi_json (= 1.11)
|
54
|
+
signet (~> 0.6)
|
55
|
+
guard (2.12.5)
|
56
|
+
formatador (>= 0.2.4)
|
57
|
+
listen (~> 2.7)
|
58
|
+
lumberjack (~> 1.0)
|
59
|
+
nenv (~> 0.1)
|
60
|
+
notiffany (~> 0.0)
|
61
|
+
pry (>= 0.9.12)
|
62
|
+
shellany (~> 0.0)
|
63
|
+
thor (>= 0.18.1)
|
64
|
+
guard-compat (1.2.1)
|
65
|
+
guard-rspec (4.5.1)
|
66
|
+
guard (~> 2.1)
|
67
|
+
guard-compat (~> 1.1)
|
68
|
+
rspec (>= 2.99.0, < 4.0)
|
69
|
+
highline (1.7.2)
|
70
|
+
hitimes (1.2.2)
|
71
|
+
i18n (0.7.0)
|
72
|
+
json (1.8.2)
|
73
|
+
jwt (1.5.0)
|
74
|
+
launchy (2.4.3)
|
75
|
+
addressable (~> 2.3)
|
76
|
+
listen (2.10.0)
|
77
|
+
celluloid (~> 0.16.0)
|
78
|
+
rb-fsevent (>= 0.9.3)
|
79
|
+
rb-inotify (>= 0.9)
|
80
|
+
little-plugger (1.1.3)
|
81
|
+
logging (2.0.0)
|
82
|
+
little-plugger (~> 1.1)
|
83
|
+
multi_json (~> 1.10)
|
84
|
+
lumberjack (1.0.9)
|
85
|
+
memoist (0.12.0)
|
86
|
+
method_source (0.8.2)
|
87
|
+
minitest (5.6.1)
|
88
|
+
multi_json (1.11.0)
|
89
|
+
multipart-post (2.0.0)
|
90
|
+
nenv (0.2.0)
|
91
|
+
notiffany (0.0.6)
|
92
|
+
nenv (~> 0.1)
|
93
|
+
shellany (~> 0.0)
|
94
|
+
parser (2.2.2.5)
|
95
|
+
ast (>= 1.1, < 3.0)
|
96
|
+
powerpack (0.1.1)
|
97
|
+
pry (0.10.1)
|
98
|
+
coderay (~> 1.1.0)
|
99
|
+
method_source (~> 0.8.1)
|
100
|
+
slop (~> 3.4)
|
101
|
+
rainbow (2.0.0)
|
102
|
+
rake (10.4.2)
|
103
|
+
rb-fsevent (0.9.5)
|
104
|
+
rb-inotify (0.9.5)
|
105
|
+
ffi (>= 0.5.0)
|
106
|
+
retriable (1.4.1)
|
107
|
+
rspec (3.2.0)
|
108
|
+
rspec-core (~> 3.2.0)
|
109
|
+
rspec-expectations (~> 3.2.0)
|
110
|
+
rspec-mocks (~> 3.2.0)
|
111
|
+
rspec-core (3.2.3)
|
112
|
+
rspec-support (~> 3.2.0)
|
113
|
+
rspec-expectations (3.2.1)
|
114
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
115
|
+
rspec-support (~> 3.2.0)
|
116
|
+
rspec-mocks (3.2.1)
|
117
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
118
|
+
rspec-support (~> 3.2.0)
|
119
|
+
rspec-support (3.2.2)
|
120
|
+
rubocop (0.31.0)
|
121
|
+
astrolabe (~> 1.3)
|
122
|
+
parser (>= 2.2.2.1, < 3.0)
|
123
|
+
powerpack (~> 0.1)
|
124
|
+
rainbow (>= 1.99.1, < 3.0)
|
125
|
+
ruby-progressbar (~> 1.4)
|
126
|
+
ruby-progressbar (1.7.5)
|
127
|
+
shellany (0.0.1)
|
128
|
+
signet (0.6.0)
|
129
|
+
addressable (~> 2.3)
|
130
|
+
extlib (~> 0.9)
|
131
|
+
faraday (~> 0.9)
|
132
|
+
jwt (~> 1.0)
|
133
|
+
multi_json (~> 1.10)
|
134
|
+
slop (3.6.0)
|
135
|
+
thor (0.19.1)
|
136
|
+
thread_safe (0.3.5)
|
137
|
+
timers (4.0.1)
|
138
|
+
hitimes
|
139
|
+
tzinfo (1.2.2)
|
140
|
+
thread_safe (~> 0.1)
|
141
|
+
|
142
|
+
PLATFORMS
|
143
|
+
ruby
|
144
|
+
|
145
|
+
DEPENDENCIES
|
146
|
+
activesupport
|
147
|
+
bundler (~> 1.6)
|
148
|
+
google-api-client
|
149
|
+
gtm!
|
150
|
+
guard-rspec (~> 4.5)
|
151
|
+
rake (~> 10.3)
|
152
|
+
rubocop (~> 0.26)
|
data/gtm-cli/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# GTM Command Line Interface
|
2
|
+
<!---
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/abrupt.svg)](http://badge.fury.io/rb/abrupt)
|
4
|
+
[![Build Status](https://travis-ci.org/manuel84/abrupt.svg?branch=master)](https://travis-ci.org/manuel84/abrupt)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/manuel84/abrupt/badges/gpa.svg)](https://codeclimate.com/github/manuel84/abrupt)
|
6
|
+
[![Test Coverage](https://codeclimate.com/github/manuel84/abrupt/badges/coverage.svg)](https://codeclimate.com/github/manuel84/abrupt)
|
7
|
+
-->
|
8
|
+
|
9
|
+
Command Line Interface for [Google Tag Manager](https://tagmanager.google.com)
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install the binary CLI:
|
14
|
+
|
15
|
+
$ gem install gtm
|
16
|
+
|
17
|
+
Create and download client_secret.json from Google Developer API Console.
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Pull tags
|
22
|
+
```shell
|
23
|
+
$ gtm pull data/
|
24
|
+
pulling tags from account 202287 into data/202287/de_nec_package/tags ................[OK]
|
25
|
+
pulling tags from account 202287 into data/202287/de_tc_kreuzfahrten/tags ......[OK]
|
26
|
+
pulling tags from account 202287 into data/202287/de_tc_kreuzfahrten_booking/tags ...[OK]
|
27
|
+
DONE
|
28
|
+
pulling tags from account 31742 into data/31742/ch_nec/tags ...........[OK]
|
29
|
+
pulling tags from account 31742 into data/31742/at_nec/tags .........................[OK]
|
30
|
+
pulling tags from account 31742 into data/31742/at_nec_booking/tags .................[OK]
|
31
|
+
pulling tags from account 31742 into data/31742/ch_nec_booking/tags .....[OK]
|
32
|
+
DONE
|
33
|
+
$ gtm pull data/202287/
|
34
|
+
pulling tags from account 202287 into data/202287/de_nec_package/tags ................[OK]
|
35
|
+
pulling tags from account 202287 into data/202287/de_tc_kreuzfahrten/tags ......[OK]
|
36
|
+
pulling tags from account 202287 into data/202287/de_tc_kreuzfahrten_booking/tags ...[OK]
|
37
|
+
DONE
|
38
|
+
$ gtm pull data/202287/de_nec_package/
|
39
|
+
pulling tags from account 202287 into data/202287/de_nec_package/tags ................[OK]
|
40
|
+
DONE
|
41
|
+
$ gtm pull data/202287/de_nec_package/tags/facebook.html
|
42
|
+
pulling tags from account 202287 into data/202287/de_nec_package/tags .[OK]
|
43
|
+
DONE
|
44
|
+
$
|
45
|
+
```
|
46
|
+
|
47
|
+
### Push tag
|
48
|
+
```shell
|
49
|
+
$ gtm push data/202287/de_tc_generic/tags/facebook.html
|
50
|
+
pushing tag data/73581867/dudda_und_dudda_de/tags/test.html to account 73581867 into container 1205187 [OK]
|
51
|
+
DONE
|
52
|
+
$
|
53
|
+
```
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it ( https://github.com/[my-github-username]/gtm/fork )
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create a new Pull Request
|
data/gtm-cli/bin/gtm
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'commander'
|
4
|
+
require_relative '../lib/gtm'
|
5
|
+
|
6
|
+
class GTMApp
|
7
|
+
include Commander::Methods
|
8
|
+
|
9
|
+
def run
|
10
|
+
program :name, 'GTM'
|
11
|
+
program :version, GTM::VERSION
|
12
|
+
program :help, 'Author', 'Manuel Dudda <manuel.dudda@gmail.com>'
|
13
|
+
program :help, 'Source Code', 'https://github.com/manuel84/gtm'
|
14
|
+
program :description, 'GTM Command Line Interface'
|
15
|
+
|
16
|
+
command :pull do |c|
|
17
|
+
c.syntax = 'gtm pull [options]'
|
18
|
+
c.description = 'Pull'
|
19
|
+
c.action do |args, options|
|
20
|
+
GTM::Bootstrap.pull args
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
command :push do |c|
|
25
|
+
c.syntax = 'gtm push [options]'
|
26
|
+
c.description = 'push'
|
27
|
+
c.action do |args, options|
|
28
|
+
GTM::Bootstrap.push args
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
run!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
GTMApp.new.run # if $0 == __FILE__
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gtm/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'gtm-cli'
|
8
|
+
spec.version = GTM::VERSION
|
9
|
+
spec.authors = ['Manuel Dudda']
|
10
|
+
spec.email = ['manuel.dudda@gmail.com']
|
11
|
+
spec.summary = 'GTM Cli'
|
12
|
+
spec.description = ''
|
13
|
+
spec.homepage = 'https://github.com/manuel84/gtm-cli'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
spec.add_runtime_dependency 'google-api-client', '~> 0.8'
|
21
|
+
spec.add_runtime_dependency 'commander', '~> 4.2'
|
22
|
+
spec.add_runtime_dependency 'activesupport', '~> 4.1'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.3'
|
26
|
+
spec.add_development_dependency 'rubocop', '~> 0.26'
|
27
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.5'
|
28
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This module is cool
|
2
|
+
# @abstract
|
3
|
+
module GTM
|
4
|
+
class Bootstrap
|
5
|
+
attr_accessor :client
|
6
|
+
|
7
|
+
def self.extract_scope(s)
|
8
|
+
full_regex = /^(?<path>.+\/|\/?)(?<account_id>\d+)\/(?<container_name>.+)\/tags\/(?<tag_file>.+)$/
|
9
|
+
container_regex = /^(?<path>.+\/|\/?)(?<account_id>\d+)\/(?<container_name>\w+)\/?$/
|
10
|
+
account_regex = /^(?<path>.+\/|\/?)(?<account_id>\d+)\/?$/
|
11
|
+
[full_regex, container_regex, account_regex].each do |r|
|
12
|
+
match = r.match s
|
13
|
+
if match
|
14
|
+
result = (match.names.zip(match.captures)).to_h.with_indifferent_access
|
15
|
+
return result.deep_symbolize_keys
|
16
|
+
end
|
17
|
+
end
|
18
|
+
result = {path: s.to_s}
|
19
|
+
result[:path] += '/' if !result[:path].blank? && !result[:path][-1].eql?('/')
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.pull(arg)
|
24
|
+
@client ||= GTM::Client.new
|
25
|
+
@client.scope = extract_scope(arg.first)
|
26
|
+
pull = GTM::Pull.new @client
|
27
|
+
pull.run
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.push(arg)
|
31
|
+
@client ||= GTM::Client.new
|
32
|
+
@client.scope = extract_scope(arg.first)
|
33
|
+
if @client.scope[:tag_file]
|
34
|
+
push = GTM::Push.new @client
|
35
|
+
push.run
|
36
|
+
else
|
37
|
+
puts 'pleas specify a single tag file, directory push is not supported (yet)'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module GTM
|
2
|
+
class AuthException < Exception
|
3
|
+
|
4
|
+
end
|
5
|
+
|
6
|
+
class Client
|
7
|
+
@@scopes = %w(https://www.googleapis.com/auth/tagmanager.delete.containers https://www.googleapis.com/auth/tagmanager.edit.containers https://www.googleapis.com/auth/tagmanager.edit.containerversions https://www.googleapis.com/auth/tagmanager.manage.accounts https://www.googleapis.com/auth/tagmanager.manage.users https://www.googleapis.com/auth/tagmanager.publish https://www.googleapis.com/auth/tagmanager.readonly)
|
8
|
+
attr_accessor :client, :gtm, :scope, :containers, :auth_file
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@client = Google::APIClient.new(
|
12
|
+
:application_name => 'gtmclient',
|
13
|
+
:application_version => '1.0.0'
|
14
|
+
)
|
15
|
+
@gtm = @client.discovered_api('tagmanager')
|
16
|
+
@scope ||= {path: ''}
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_auth_file
|
20
|
+
auth_path = "#{@scope[:path]}.dump"
|
21
|
+
FileUtils::mkdir_p auth_path
|
22
|
+
@auth_file = "#{auth_path}/auth"
|
23
|
+
data = File.read(@auth_file) rescue nil
|
24
|
+
auth = Marshal.load(data) rescue nil
|
25
|
+
@client.authorization = auth
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
set_auth_file
|
30
|
+
tries = 0
|
31
|
+
begin
|
32
|
+
result = @client.execute(
|
33
|
+
api_method: @gtm.accounts.list,
|
34
|
+
parameters: {
|
35
|
+
}
|
36
|
+
)
|
37
|
+
tries += 1
|
38
|
+
raise GTM::AuthException if result.data['error'] && result.data.error['code']
|
39
|
+
@accounts = result.data.accounts
|
40
|
+
yield @accounts
|
41
|
+
puts 'DONE'
|
42
|
+
rescue AuthException
|
43
|
+
client_secrets = Google::APIClient::ClientSecrets.load
|
44
|
+
flow = Google::APIClient::InstalledAppFlow.new(
|
45
|
+
client_id: client_secrets.client_id,
|
46
|
+
client_secret: client_secrets.client_secret,
|
47
|
+
scope: @@scopes
|
48
|
+
)
|
49
|
+
|
50
|
+
auth = flow.authorize
|
51
|
+
data = Marshal.dump(auth)
|
52
|
+
@client.authorization = auth
|
53
|
+
File.write @auth_file, data
|
54
|
+
retry if tries < 2
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'google/api_client'
|
2
|
+
require 'google/api_client/client_secrets'
|
3
|
+
require 'google/api_client/auth/installed_app'
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'pp'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
module GTM
|
9
|
+
class Pull
|
10
|
+
attr_accessor :client
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@client = client
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
account_ids.each do |account_id|
|
18
|
+
@client.scope[:account_id] = account_id
|
19
|
+
pull_tags
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def account_ids
|
24
|
+
if @client.scope[:account_id]
|
25
|
+
[@client.scope[:account_id]]
|
26
|
+
else
|
27
|
+
get_account_ids
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_account_ids
|
32
|
+
@client.run do |accounts|
|
33
|
+
account_ids = accounts.map { |a| a['accountId'] }
|
34
|
+
return account_ids
|
35
|
+
end
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_container(account_id)
|
40
|
+
result = @client.client.execute(
|
41
|
+
api_method: @client.gtm.accounts.containers.list,
|
42
|
+
parameters: {
|
43
|
+
accountId: account_id
|
44
|
+
}
|
45
|
+
)
|
46
|
+
result.data.containers
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_tags(account_id, container_id)
|
50
|
+
result = @client.client.execute(
|
51
|
+
api_method: @client.gtm.accounts.containers.tags.list,
|
52
|
+
parameters: {
|
53
|
+
accountId: account_id,
|
54
|
+
containerId: container_id
|
55
|
+
}
|
56
|
+
)
|
57
|
+
result.data.tags
|
58
|
+
end
|
59
|
+
|
60
|
+
def pull_tags
|
61
|
+
container_scope = @client.scope[:container_name]
|
62
|
+
@client.run do |accounts|
|
63
|
+
account_ids = accounts.map { |a| a['accountId'] }
|
64
|
+
if account_ids.include? @client.scope[:account_id]
|
65
|
+
containers = get_container @client.scope[:account_id]
|
66
|
+
containers.each do |container|
|
67
|
+
container_name = container['name'].parameterize.underscore
|
68
|
+
next if container_scope && !container_scope.include?(container_name)
|
69
|
+
tags_path = "#{@client.scope[:path]}#{@client.scope[:account_id]}/#{container_name}/tags"
|
70
|
+
meta_tags_path = "#{@client.scope[:path]}/.dump/meta/#{@client.scope[:account_id]}/#{container_name}/tags"
|
71
|
+
FileUtils::mkdir_p tags_path
|
72
|
+
FileUtils::mkdir_p meta_tags_path
|
73
|
+
tags = get_tags @client.scope[:account_id], container['containerId']
|
74
|
+
print "pulling tags from account #{container['accountId']} into #{tags_path} "
|
75
|
+
tags.each do |tag|
|
76
|
+
tag_name = tag['name'].parameterize.underscore
|
77
|
+
if tag.parameter.last && tag.parameter.last.type.eql?('template') && tag.parameter.last.key.in?(%w(html))
|
78
|
+
template = tag.parameter.last
|
79
|
+
File.open("#{tags_path}/#{tag_name}.#{template.key}", 'w') do |f|
|
80
|
+
f.write template.value
|
81
|
+
end
|
82
|
+
data = Marshal.dump(tag.to_hash)
|
83
|
+
File.open("#{meta_tags_path}/#{tag_name}.#{template.key}.dump", 'w') do |f|
|
84
|
+
f.write data
|
85
|
+
end
|
86
|
+
print '.'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
puts '[OK]'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'google/api_client'
|
2
|
+
require 'google/api_client/client_secrets'
|
3
|
+
require 'google/api_client/auth/installed_app'
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
module GTM
|
8
|
+
class Push
|
9
|
+
attr_accessor :client
|
10
|
+
|
11
|
+
def initialize(client)
|
12
|
+
@client = client
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
tag_file = "#{@client.scope[:account_id]}/#{@client.scope[:container_name]}/tags/#{@client.scope[:tag_file]}"
|
17
|
+
data = File.read("#{@client.scope[:path]}.dump/meta/#{tag_file}.dump")
|
18
|
+
tag = Marshal.load(data)
|
19
|
+
tag_content = File.read("#{@client.scope[:path]}#{tag_file}")
|
20
|
+
body = tag
|
21
|
+
body['parameter'].last['value'] = tag_content
|
22
|
+
@client.run do |_accounts|
|
23
|
+
print "pushing tag #{"#{@client.scope[:path]}#{tag_file}"} for account #{tag['accountId']} into container #{tag['containerId']} "
|
24
|
+
result = @client.client.execute(
|
25
|
+
api_method: @client.gtm.accounts.containers.tags.update,
|
26
|
+
parameters: {
|
27
|
+
accountId: tag['accountId'],
|
28
|
+
containerId: tag['containerId'],
|
29
|
+
tagId: tag['tagId']
|
30
|
+
},
|
31
|
+
body_object: body
|
32
|
+
)
|
33
|
+
puts '[OK]'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/gtm-cli/lib/gtm.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe GTM::Bootstrap do
|
4
|
+
context '::extract_scope' do
|
5
|
+
it 'extracts empty scope' do
|
6
|
+
args = ['', nil]
|
7
|
+
args.each do |arg|
|
8
|
+
scope = GTM::Bootstrap.extract_scope arg
|
9
|
+
expect(scope).to eql({path: ''})
|
10
|
+
end
|
11
|
+
args = %w(data data/)
|
12
|
+
args.each do |arg|
|
13
|
+
scope = GTM::Bootstrap.extract_scope arg
|
14
|
+
expect(scope).to eql({
|
15
|
+
path: 'data/'
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'extracts only account_id' do
|
21
|
+
args = %w(data/202287 data/202287/)
|
22
|
+
args.each do |arg|
|
23
|
+
scope = GTM::Bootstrap.extract_scope arg
|
24
|
+
expect(scope).to eql({
|
25
|
+
path: 'data/',
|
26
|
+
account_id: '202287'
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'extracts account_id and container' do
|
32
|
+
args = %w(202287/de_nec_package/ 202287/de_nec_package)
|
33
|
+
args.each do |arg|
|
34
|
+
scope = GTM::Bootstrap.extract_scope arg
|
35
|
+
expect(scope).to eql({
|
36
|
+
path: '',
|
37
|
+
account_id: '202287',
|
38
|
+
container_name: 'de_nec_package'
|
39
|
+
})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'extracts account_id, container and tag' do
|
44
|
+
arg = '202287/de_nec_package/tags/facebook.html'
|
45
|
+
scope = GTM::Bootstrap.extract_scope arg
|
46
|
+
expect(scope).to eql({
|
47
|
+
path: '',
|
48
|
+
account_id: '202287',
|
49
|
+
container_name: 'de_nec_package',
|
50
|
+
tag_file: 'facebook.html'
|
51
|
+
})
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'extracts the correct path' do
|
55
|
+
arg = '/usr/an/absolute_path/202287'
|
56
|
+
scope = GTM::Bootstrap.extract_scope arg
|
57
|
+
expect(scope[:path]).to eql('/usr/an/absolute_path/')
|
58
|
+
args = %w(long/path/to/test/here/we/go long/path/to/test/here/we/go/202287 long/path/to/test/here/we/go/202287/de_nec_package/tags/facebook.html long/path/to/test/here/we/go/202287/de_nec_package)
|
59
|
+
args.each do |arg|
|
60
|
+
scope = GTM::Bootstrap.extract_scope arg
|
61
|
+
expect(scope[:path]).to eql('long/path/to/test/here/we/go/')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,92 @@
|
|
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
|
+
require 'gtm-cli'
|
20
|
+
RSpec.configure do |config|
|
21
|
+
# rspec-expectations config goes here. You can use an alternate
|
22
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
23
|
+
# assertions if you prefer.
|
24
|
+
config.expect_with :rspec do |expectations|
|
25
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
26
|
+
# and `failure_message` of custom matchers include text for helper methods
|
27
|
+
# defined using `chain`, e.g.:
|
28
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
29
|
+
# # => "be bigger than 2 and smaller than 4"
|
30
|
+
# ...rather than:
|
31
|
+
# # => "be bigger than 2"
|
32
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
36
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
37
|
+
config.mock_with :rspec do |mocks|
|
38
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
39
|
+
# a real object. This is generally recommended, and will default to
|
40
|
+
# `true` in RSpec 4.
|
41
|
+
mocks.verify_partial_doubles = true
|
42
|
+
end
|
43
|
+
|
44
|
+
# The settings below are suggested to provide a good initial experience
|
45
|
+
# with RSpec, but feel free to customize to your heart's content.
|
46
|
+
=begin
|
47
|
+
# These two settings work together to allow you to limit a spec run
|
48
|
+
# to individual examples or groups you care about by tagging them with
|
49
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
50
|
+
# get run.
|
51
|
+
config.filter_run :focus
|
52
|
+
config.run_all_when_everything_filtered = true
|
53
|
+
|
54
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
55
|
+
# recommended. For more details, see:
|
56
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
57
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
58
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
59
|
+
config.disable_monkey_patching!
|
60
|
+
|
61
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
62
|
+
# be too noisy due to issues in dependencies.
|
63
|
+
config.warnings = true
|
64
|
+
|
65
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
66
|
+
# file, and it's useful to allow more verbose output when running an
|
67
|
+
# individual spec file.
|
68
|
+
if config.files_to_run.one?
|
69
|
+
# Use the documentation formatter for detailed output,
|
70
|
+
# unless a formatter has already been configured
|
71
|
+
# (e.g. via a command-line flag).
|
72
|
+
config.default_formatter = 'doc'
|
73
|
+
end
|
74
|
+
|
75
|
+
# Print the 10 slowest examples and example groups at the
|
76
|
+
# end of the spec run, to help surface which specs are running
|
77
|
+
# particularly slow.
|
78
|
+
config.profile_examples = 10
|
79
|
+
|
80
|
+
# Run specs in random order to surface order dependencies. If you find an
|
81
|
+
# order dependency and want to debug it, you can fix the order by providing
|
82
|
+
# the seed, which is printed after each run.
|
83
|
+
# --seed 1234
|
84
|
+
config.order = :random
|
85
|
+
|
86
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
87
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
88
|
+
# test failures related to randomization by passing the same `--seed` value
|
89
|
+
# as the one that triggered the failure.
|
90
|
+
Kernel.srand config.seed
|
91
|
+
=end
|
92
|
+
end
|
metadata
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gtm-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.9
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Manuel Dudda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: google-api-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: commander
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.26'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.26'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '4.5'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.5'
|
111
|
+
description: ''
|
112
|
+
email:
|
113
|
+
- manuel.dudda@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".ruby-gemset"
|
120
|
+
- ".ruby-version"
|
121
|
+
- gtm-cli/.gitignore
|
122
|
+
- gtm-cli/.rspec
|
123
|
+
- gtm-cli/Gemfile
|
124
|
+
- gtm-cli/Gemfile.lock
|
125
|
+
- gtm-cli/README.md
|
126
|
+
- gtm-cli/bin/gtm
|
127
|
+
- gtm-cli/gtm-cli.gemspec
|
128
|
+
- gtm-cli/lib/gtm.rb
|
129
|
+
- gtm-cli/lib/gtm/bootstrap.rb
|
130
|
+
- gtm-cli/lib/gtm/client.rb
|
131
|
+
- gtm-cli/lib/gtm/pull.rb
|
132
|
+
- gtm-cli/lib/gtm/push.rb
|
133
|
+
- gtm-cli/lib/gtm/version.rb
|
134
|
+
- gtm-cli/spec/gtm/bootstrap_spec.rb
|
135
|
+
- gtm-cli/spec/spec_helper.rb
|
136
|
+
homepage: https://github.com/manuel84/gtm-cli
|
137
|
+
licenses:
|
138
|
+
- MIT
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.4.6
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: GTM Cli
|
160
|
+
test_files: []
|