gazer 0.2.17 → 0.2.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87c9fc855fb39c5b2db03afb3495706a6acbc341
4
- data.tar.gz: 924bf3c6fd99783bd6d94960c9aac2a0404e6c36
3
+ metadata.gz: 2748a37dd51a0543b381ea57739cff2f15d1d437
4
+ data.tar.gz: 8638b34bc120de4baa9a50365186bd6d05d9e787
5
5
  SHA512:
6
- metadata.gz: fe576cfebc5fa0f91339c07934818239899d214cb0c738fa3ff403a09129c2d97eb27fa8f5d7ba53d5caa9ba93f8a10f75b09f4490b0418589fa8d2dfeb3146e
7
- data.tar.gz: 6bd4af2afb618333b1cd5ecff92bb4d4acd03289bcf26aac5f323a98c632e1cafbbc48baa7f8ff70cdbc6d562e5ef57898a56188623192ba01284a1589ff625e
6
+ metadata.gz: b580425e8b9c566d0413fc5e67cfd55df01887d73f13796a5eff46f20e1b552910f3d5b63d979fa40ac17e93941a33989fd388f7b57cbd37e0d075d87ce198d8
7
+ data.tar.gz: c51d839b274280e4722d72aaf9ed761be0304a04a4b6f07b8191423c09a7c1a45859ba315169673db5469d6c16b48efa96d54ccc6b976ff2d9a3eb819d11e4f2
data/.gitignore CHANGED
@@ -13,3 +13,6 @@
13
13
  *~
14
14
  *.swp
15
15
  *.json
16
+ gzr.code-workspace
17
+ /output/
18
+ scratch
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gazer (0.2.17)
4
+ gazer (0.2.18)
5
5
  looker-sdk (~> 0.0.6)
6
6
  netrc (~> 0.11.0)
7
7
  pastel (~> 0.7.2)
@@ -145,4 +145,4 @@ RUBY VERSION
145
145
  ruby 2.3.3p222
146
146
 
147
147
  BUNDLED WITH
148
- 1.16.2
148
+ 1.16.6
data/README.md CHANGED
@@ -129,7 +129,7 @@ gzr group ls --host foo.bar.mycompany.com
129
129
 
130
130
  #### group member_groups
131
131
 
132
- The command `gzr group member_group GROUP_ID` will list the group that have been added as
132
+ The command `gzr group member_group GROUP_ID` will list the groups that have been added
133
133
  as members of the given group id.
134
134
 
135
135
  ```
@@ -143,7 +143,7 @@ $ gzr group member_group 24 --host foo.bar.mycompany.com
143
143
 
144
144
  #### group member_users
145
145
 
146
- The command `gzr group member_users GROUP_ID` will list the users that have been added as
146
+ The command `gzr group member_users GROUP_ID` will list the users that have been added
147
147
  as members of the given group id.
148
148
 
149
149
  ```
@@ -239,7 +239,7 @@ John Smith
239
239
  └── (d) Indicator Dashboard 2011
240
240
  ```
241
241
 
242
- The same arguments are accepted as by `space ls`.
242
+ The same arguments are accepted as the `space ls` command.
243
243
 
244
244
  #### space cat
245
245
 
@@ -302,9 +302,9 @@ Looks and Dashboards will be located in the space directories in files named lik
302
302
  $ gzr space export 758 --host foo.bar.mycompany.com --dir .
303
303
  ```
304
304
 
305
- One interesting use of exporting a space into a directory tree is that it can be placed under version control
306
- using a tool like git. In that way user defined content changes can be tracked over time, and older versions
307
- of content can be restored if desired.
305
+ One interesting consequence of exporting a space into a directory tree is that you can then place its
306
+ contents under version control using a tool like git. In this way user defined content changes can be
307
+ tracked over time, and older versions of content can be restored if desired.
308
308
 
309
309
  Alternately, the space can be exported into a `tar` style archive file with the switch `--tar FILENAME`.
310
310
 
@@ -366,8 +366,8 @@ $ gzr look rm 758 --host foo.bar.mycompany.com
366
366
  The `look import LOOK_FILE SPACE_ID` command is used to import a look from a file. If a look by the same
367
367
  name exists in that space then the `--force` switch must be used.
368
368
 
369
- Gazer will attempt to update the existing look of the same name, rather than create a new look. In
370
- that way the look id, schedules, permissions, etc. will be preserved.
369
+ Gazer will attempt to update an existing look of the same name, rather than create a new look. In
370
+ this way the look id, share URLs, schedules, permissions, etc. will be preserved.
371
371
 
372
372
  ```
373
373
  $ gzr look import Path/To/Look_123_My\ Look.json 123 --host foo.bar.mycompany.com --force
@@ -389,6 +389,82 @@ JSON data for dashboard
389
389
  The output document can be very long. Usually one will use the switch `--dir DIRECTORY` to
390
390
  save to a file. The file will be named `Dashboard_{DASHBOARD_ID}_{DASHBOARD_TITLE}.json`.
391
391
 
392
+ The `--transform FILE` switch can be used to update the output document. This is useful to automatically
393
+ perform tasks when promoting dashboards to upper environments, such as adding header or footer
394
+ text tiles, replacing model or explore names, or updating filter expressions. The `FILE` parameter
395
+ accepts a fully-qualified path to a JSON file describing the transformations to apply.
396
+
397
+ ```
398
+ $ gzr dashboard cat 192 --host foo.bar.mycompany.com --transform path/to/transforms.json
399
+ JSON data for dashboard modified by any transformations expressed in the transform file
400
+ ```
401
+
402
+ The transform file uses a familiar JSON syntax. Within the file, you can define any number
403
+ of `dashboard_elements` to append to your existing dashboard. Elements must be placed in either
404
+ the top row or the bottom row of the existing dashboard, specified by the `position` attribute.
405
+ You must also specify the `width` and `height` of your new elements.
406
+
407
+ You can also define any number of `replacements`, which perform a simple find and replace
408
+ within the JSON output based on the key-value pairs listed. This can be used to automatically
409
+ replace model names or update filters for existing elements. You must escape double-quotes.
410
+
411
+ Example JSON transform file:
412
+ ```
413
+ {
414
+ "dashboard_elements": [
415
+ {
416
+ "position": "top",
417
+ "width": 12,
418
+ "height": 2,
419
+ "body_text": "Production Version of Dashboard (deployed 2019-06-18)",
420
+ "body_text_as_html": "<p>Production Version of Dashboard (deployed 2019-06-18)</p>",
421
+ "note_display": null,
422
+ "note_state": null,
423
+ "note_text": null,
424
+ "note_text_as_html": null,
425
+ "subtitle_text": "",
426
+ "title": null,
427
+ "title_hidden": false,
428
+ "title_text": "",
429
+ "type": "text"
430
+ },
431
+ {
432
+ "position": "bottom",
433
+ "width": 6,
434
+ "height": 2,
435
+ "body_text": "Please contact the Business Intelligence Help Desk for any issues with this dashboard",
436
+ "body_text_as_html": "<p>Please contact the Business Intelligence Help Desk for any issues with this dashboard</p>",
437
+ "note_display": null,
438
+ "note_state": null,
439
+ "note_text": null,
440
+ "note_text_as_html": null,
441
+ "subtitle_text": "",
442
+ "title": null,
443
+ "title_hidden": false,
444
+ "title_text": "",
445
+ "type": "text"
446
+ }
447
+ ],
448
+ "replacements": [
449
+ {
450
+ "\"model\": \"staging\",": "\"model\": \"production\","
451
+ },
452
+ {
453
+ "\"filter_expression\": \"not(is_null(${view.allowed_user}))\": "\"filter_expression\": \"${view.allowed_user} = _user_attributes['username']\","
454
+ }
455
+ ]
456
+ }
457
+ ```
458
+ | WARNING: You will not be able to overwrite dashboards that have been transformed! |
459
+ | --- |
460
+
461
+ In other words, you can&rsquo;t use the `--force` switch to replace a previously-transformed dashboard. Instead,
462
+ you&rsquo;ll need to delete and recreate the dashboard. If you have stable content URLs enabled on your
463
+ instance, the `slug` parameter ensures the URL for your dashboard won&rsquo;t change.
464
+
465
+ This is because it is impossible to know the element IDs for elements that were added by the `--transform` operation,
466
+ which makes it impossible to synchronize these elements in the future.
467
+
392
468
  #### dashboard rm
393
469
 
394
470
  The `dashboard rm DASHBOARD_ID` command is used to delete a dashboard.
@@ -399,13 +475,13 @@ $ gzr dashboard rm 192 --host foo.bar.mycompany.com
399
475
 
400
476
  #### dashboard import
401
477
 
402
- The `dashboard import DASHBAORD_FILE SPACE_ID` command is used to import a dashboard and
403
- its associated looks from a file. If a dashbaord or look by the same
478
+ The `dashboard import DASHBOARD_FILE SPACE_ID` command is used to import a dashboard and
479
+ its associated looks from a file. If a dashboard or look by the same
404
480
  name exists in that space then the `--force` switch must be used.
405
481
 
406
- Gazer will attempt to update the existing dashboard or look of the same name, rather than
407
- create a new dashboard or look. In
408
- that way the id, schedules, permissions, etc. will be preserved.
482
+ Gazer will attempt to update an existing dashboard or look of the same name,
483
+ rather than create a new dashboard or look. In this way the id, share URLs,
484
+ schedules, permissions, etc. will be preserved.
409
485
 
410
486
  ```
411
487
  $ gzr dashboard import Path/To/Dashboard_123_My\ Dash.json 123 --host foo.bar.mycompany.com --force
@@ -417,7 +493,7 @@ The command `gzr connection help` will show details about subcommands of the con
417
493
 
418
494
  #### connection ls
419
495
 
420
- The command `gzr connection ls` will list the connections that have been defined in the Looker instance.
496
+ The command `gzr connection ls` will list the connections that exist in the Looker instance.
421
497
 
422
498
  ```
423
499
  $ gzr connection ls --host foo.bar.mycompany.com
@@ -492,7 +568,7 @@ The command `gzr model help` will show details about subcommands of the model co
492
568
 
493
569
  #### model ls
494
570
 
495
- The command `gzr model ls` will list the models that have been defined in the Looker instance.
571
+ The command `gzr model ls` will list the models that exist in the Looker instance.
496
572
 
497
573
  ```
498
574
  $ gzr model ls --host foo.bar.mycompany.com
@@ -36,6 +36,8 @@ module Gzr
36
36
  desc: 'Directory to store output file'
37
37
  method_option :plans, type: :boolean,
38
38
  desc: 'Include scheduled plans'
39
+ method_option :transform, type: :string,
40
+ desc: 'Fully-qualified path to a JSON file describing the transformations to apply'
39
41
  def cat(dashboard_id)
40
42
  if options[:help]
41
43
  invoke :help, ['cat']
@@ -43,8 +43,9 @@ module Gzr
43
43
  def execute(*args, input: $stdin, output: $stdout)
44
44
  say_warning("options: #{@options.inspect}") if @options[:debug]
45
45
  with_session("3.1") do
46
- data = query_dashboard(@dashboard_id)
47
- data.to_attrs()[:dashboard_elements].each_index do |i|
46
+ result = query_dashboard(@dashboard_id)
47
+ data = result.to_attrs
48
+ data[:dashboard_elements].each_index do |i|
48
49
  element = data[:dashboard_elements][i]
49
50
  if element[:merge_result_id]
50
51
  merge_result = merge_query(element[:merge_result_id])
@@ -56,8 +57,59 @@ module Gzr
56
57
  end
57
58
  end
58
59
  data[:scheduled_plans] = query_scheduled_plans_for_dashboard(@dashboard_id,"all") if @options[:plans]
59
- write_file(@options[:dir] ? "Dashboard_#{data.id}_#{data.title}.json" : nil, @options[:dir], nil, output) do |f|
60
- f.puts JSON.pretty_generate(data.to_attrs)
60
+
61
+ replacements = {}
62
+ if @options[:transform]
63
+
64
+ max_row = 0
65
+ data[:dashboard_layouts][0][:dashboard_layout_components].each_index do |i|
66
+ component = data[:dashboard_layouts][0][:dashboard_layout_components][i]
67
+ if component[:row] + component[:height] > max_row
68
+ max_row = component[:row] + component[:height] + 4
69
+ end
70
+ end
71
+
72
+ read_file(@options[:transform]) do |transform|
73
+ i = 0
74
+ transform[:dashboard_elements].collect! do |e|
75
+ i += 1
76
+ # there is no significance to 9900, we just need to prevent ID collisions
77
+ e['id'] = 9900 + i
78
+ data[:dashboard_elements] << e
79
+
80
+ # when inserting an element into the top row, shift the other elements down according to the height of the inserted element
81
+ if e[:position] === 'top'
82
+ data[:dashboard_layouts][0][:dashboard_layout_components].each_index do |i|
83
+ component = data[:dashboard_layouts][0][:dashboard_layout_components][i]
84
+ component[:row] = component[:row] + e[:height]
85
+ end
86
+ row = '0'
87
+ elsif e[:position] === 'bottom'
88
+ row = max_row.to_s
89
+ end
90
+
91
+ column = '0'
92
+ width = e[:width].to_s
93
+ height = e[:height].to_s
94
+ data[:dashboard_layouts][0][:dashboard_layout_components] << JSON.parse('{"id":' + e['id'].to_s + ',"dashboard_layout_id":1,"dashboard_element_id":' + e['id'].to_s + ''',"row":' + row + ',"column":' + column + ',"width":' + width + ',"height":' + height + ',"deleted":false,"element_title_hidden":false,"vis_type":"' + e[:type].to_s + '","can":{"index":true,"show":true,"create":true,"update":true,"destroy":true}}')
95
+ end
96
+
97
+ transform[:replacements].collect! do |e|
98
+ replacements[e.keys.first.to_s] = e[e.keys[0]]
99
+ end
100
+
101
+ end
102
+ end
103
+
104
+ outputJSON = JSON.pretty_generate(data)
105
+
106
+ replacements.each do |k,v|
107
+ say_warning("Replaced #{k} with #{v}") if @options[:debug]
108
+ outputJSON.gsub! k,v
109
+ end
110
+
111
+ write_file(@options[:dir] ? "Dashboard_#{result.id}_#{result.title}.json" : nil, @options[:dir], nil, output) do |f|
112
+ f.puts outputJSON
61
113
  end
62
114
  end
63
115
  end
@@ -49,7 +49,7 @@ module Gzr
49
49
  test_dir = base + Pathname.new(path_part)
50
50
  Dir.mkdir(test_dir) unless (test_dir.exist? && test_dir.directory?)
51
51
  end if p
52
- file = Pathname.new(file_name.gsub('/',"\u{2215}")) if file_name
52
+ file = Pathname.new(file_name.gsub('/',"\u{2215}").gsub(':','')) if file_name
53
53
  file = p + file if p
54
54
  file = base + file if base
55
55
  f = File.open(file, "wt") if file
@@ -20,5 +20,5 @@
20
20
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  module Gzr
23
- VERSION = "0.2.17"
23
+ VERSION = "0.2.18"
24
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.17
4
+ version: 0.2.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike DeAngelo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-31 00:00:00.000000000 Z
11
+ date: 2019-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-reader