Skip to content

Commit

Permalink
Merge pull request #188 from looker-open-source/lookml-dashboards
Browse files Browse the repository at this point in the history
LookML Dashboard support
  • Loading branch information
fabio-looker authored Jul 31, 2024
2 parents 616fd71 + ae83373 commit 5057903
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 63 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
npm ci
- name: Lint
run: npm run lint
- name: Install js-yaml (optional dependency)
run: npm install --no-save js-yaml
- name: Run tests
run: npm test
env:
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ If your LookML project doesn't have a manifest.lkml file, you may want to consid
- **rule: rule_name** - Recommended. Used to opt-in to built-in rules and to specify custom rules. See [customizing LAMS](https://looker-open-source.github.io/look-at-me-sideways/customizing-lams)
- **rule_exemptions** - Optional. Originally used in 1 & v2 to opt-out of rules globally. A global opt-out can still be useful for opting-out of certain "sub rules" that a rule may return without opting-out of the entire rule. See [customizing LAMS](https://looker-open-source.github.io/look-at-me-sideways/customizing-lams)

### Optional Dependencies

- `js-yaml` is not automatically installed with LAMS, but you may explicitly install it if you want to write custom rules that lint against the contents of a LookML Dashboard, which is a YAML-based file. In this case, also make sure to pass a `source` argument, as the default `source` does not includes `.dashboard.lookml` files.

## About

### Release Notes
Expand Down
51 changes: 51 additions & 0 deletions __tests__/dummy-projects/28-lookml-dashboards/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const lams = require('../../../index.js')
const mocks = require('../../../lib/mocks.js')
const path= require('path')
const options = {
reporting:"no",
cwd:__dirname,
source:"{manifest.lkml,*.model.lkml,*.dashboard.lookml}"
};
require('../../../lib/expect-to-contain-message');
const log = x=>console.log(x)
const testProjectName = __dirname.split(path.sep).slice(-1)[0];

describe('Projects', () => {
describe(testProjectName + " (needs js-yaml optional dependency)", () => {
let {spies, process, console} = mocks()
let messages
beforeAll( async () => {
messages = await lams(options,{process, console})
})
it("should not error out", ()=> {
expect(console.error).not.toHaveBeenCalled()
});
it("it should not contain any unexpected parser (P0) errors", ()=> {
expect({messages}).not.toContainMessage({
rule: "P0",
level: "error"
});
});
it("it should not contain any parser syntax (P1) errors", ()=> {
expect({messages}).not.toContainMessage({
rule: "P1",
level: "error"
});
});

it("it should match DASH_1 (3 match, 0 exempt, 1 error)", ()=> {
expect({messages}).toContainMessage({
rule: "DASH_1",
level: "info",
description: "Rule DASH_1 summary: 3 matches, 0 matches exempt, and 1 errors"
});
});

it("it should error on DASH_1", ()=> {
expect({messages}).toContainMessage({
rule: "DASH_1",
level: "error"
});
});
});
});
8 changes: 8 additions & 0 deletions __tests__/dummy-projects/28-lookml-dashboards/manifest.lkml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#LAMS
#rule: DASH_1 {
# description: "`model` attribute should not be set (allow inheritance based on model inclusion)"
# match: "$.model.*.dashboard.*[0].elements.*"
# expr_rule:
# (=== ::match:model undefined)
# ;;
#}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
- dashboard: user_segments
title: User segments
layout: newspaper
embed_style:
background_color: "#ff4141"
show_title: false
title_color: "#3a4245"
show_filters_bar: true
tile_text_color: "#3a4245"
text_tile_text_color: "#caff37"
elements:
- name: User segments
title: User segments
model: thelook
explore: users
type: looker_pie
fields:
- users.gender
- users.count
filters:
users.state: ''
sorts:
- users.count desc
limit: 500
column_limit: 50
query_timezone: America/Los_Angeles
value_labels: legend
label_type: labPer
stacking: ''
show_value_labels: false
label_density: 25
legend_position: center
x_axis_gridlines: false
y_axis_gridlines: true
show_view_names: true
limit_displayed_rows: false
y_axis_combined: true
show_y_axis_labels: true
show_y_axis_ticks: true
y_axis_tick_density: default
y_axis_tick_density_custom: 5
show_x_axis_label: true
show_x_axis_ticks: true
x_axis_scale: auto
y_axis_scale_mode: linear
ordering: none
show_null_labels: false
show_totals_labels: false
show_silhouette: false
totals_color: "#808080"
series_types: {}
listen:
State: users.state
row: 0
col: 0
width: 12
height: 8
- name: Markdown
type: text
title_text: Markdown
body_text: "Inline-style: \n![alt text](https://wwwstatic-a.lookercdn.com/homepage/new_home/looker.svg)\n\
\nReference-style: \n![alt text][logo]\n\n[logo]: https://wwwstatic-a.lookercdn.com/homepage/new_home/looker.svg"
row: 0
col: 12
width: 12
height: 6
- name: Md
type: text
title_text: Md
body_text: "Inline-style: \n![alt text](https://wwwstatic-a.lookercdn.com/homepage/new_home/looker.svg)\n\
\nReference-style: \n![alt text][logo]\n\n[logo]: https://wwwstatic-a.lookercdn.com/homepage/new_home/looker.svg"
row: 8
col: 0
width: 24
height: 8
filters:
- name: State
title: State
type: field_filter
default_value:
model: thelook
explore: orderss
field: users.state
listens_to_filters: []
allow_multiple_values: true
required: false
- name: City
title: City
type: field_filter
default_value: ''
model: thelook
explore: orders
field: users.city
listens_to_filters:
- State
allow_multiple_values: true
required: false
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: "*.dashboard"
70 changes: 39 additions & 31 deletions npm-shrinkwrap.dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"fromentries": "^1.3.2",
"jsonpath-plus": "^7.2.0",
"liyad": "^0.2.4",
"lookml-parser": "^6.8.2",
"lookml-parser": "^6.9.1",
"minimist": "^1.2.6",
"require-from-string": "^2.0.2"
},
Expand Down Expand Up @@ -1393,7 +1393,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
"devOptional": true
},
"node_modules/asynckit": {
"version": "0.4.0",
Expand Down Expand Up @@ -1538,12 +1538,12 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
Expand Down Expand Up @@ -2320,9 +2320,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
Expand Down Expand Up @@ -3613,7 +3613,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"devOptional": true,
"dependencies": {
"argparse": "^2.0.1"
},
Expand Down Expand Up @@ -3806,9 +3806,9 @@
"dev": true
},
"node_modules/lookml-parser": {
"version": "6.8.2",
"resolved": "https://registry.npmjs.org/lookml-parser/-/lookml-parser-6.8.2.tgz",
"integrity": "sha512-iuhCtKrbr4iuQ1DkiHi4y3yepK5PqttEdZMYP8w9gpm0tr0cB4rAqqpHIcndoiy+m6wnS3UfhjK3pFP8AIrXow==",
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/lookml-parser/-/lookml-parser-6.9.1.tgz",
"integrity": "sha512-2xq76z1Igpnz1/j0o14qxHp6FpWfDRvmDVKjk71RouLW81yTp6NAqwyCM5r0UdjIgc9RTPGNY6G2DwG1XBWqFg==",
"dependencies": {
"bluebird": "^3.5.1",
"glob": "^7.1.2",
Expand All @@ -3817,6 +3817,14 @@
},
"bin": {
"lookml-parser": "cli.js"
},
"peerDependencies": {
"js-yaml": "^4.1.0"
},
"peerDependenciesMeta": {
"js-yaml": {
"optional": true
}
}
},
"node_modules/lru-cache": {
Expand Down Expand Up @@ -4950,9 +4958,9 @@
}
},
"node_modules/ws": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"dev": true,
"engines": {
"node": ">=8.3.0"
Expand Down Expand Up @@ -6105,7 +6113,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
"devOptional": true
},
"asynckit": {
"version": "0.4.0",
Expand Down Expand Up @@ -6225,12 +6233,12 @@
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
}
},
"browser-process-hrtime": {
Expand Down Expand Up @@ -6821,9 +6829,9 @@
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
Expand Down Expand Up @@ -7820,7 +7828,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"devOptional": true,
"requires": {
"argparse": "^2.0.1"
}
Expand Down Expand Up @@ -7959,9 +7967,9 @@
"dev": true
},
"lookml-parser": {
"version": "6.8.2",
"resolved": "https://registry.npmjs.org/lookml-parser/-/lookml-parser-6.8.2.tgz",
"integrity": "sha512-iuhCtKrbr4iuQ1DkiHi4y3yepK5PqttEdZMYP8w9gpm0tr0cB4rAqqpHIcndoiy+m6wnS3UfhjK3pFP8AIrXow==",
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/lookml-parser/-/lookml-parser-6.9.1.tgz",
"integrity": "sha512-2xq76z1Igpnz1/j0o14qxHp6FpWfDRvmDVKjk71RouLW81yTp6NAqwyCM5r0UdjIgc9RTPGNY6G2DwG1XBWqFg==",
"requires": {
"bluebird": "^3.5.1",
"glob": "^7.1.2",
Expand Down Expand Up @@ -8841,9 +8849,9 @@
}
},
"ws": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"dev": true,
"requires": {}
},
Expand Down
Loading

0 comments on commit 5057903

Please sign in to comment.