A frequently asked question by those that develop in Looker is around how to write code that is reusable, self-explanatory and reliable. This is often because they have been working on the same model for a significant period of time, very often with multiple contributors, and it has become bloated and very hard to maintain and build upon.
The Why
Look At Me Sideways (LAMS) seeks to address this problem by:
Helping developer teams adhere to best practices
Aiding anyone interested in cleaning and refactoring their LookML model
Ensuring consistency and a certain level of code quality
Automating the pull request review process for those that enforce them
Maintaining a clean master branch at all times
The How
LAMS is a linter and a style guide that picks up and flags anti-patterns or anything that deviates from recommended LookML constructs. It also explains exactly whatâs wrong as well as provides common best-practice solutions and/or alternatives. The style guide itself is intended to evolve over time as new conventions are identified, suggested and/or potentially contributed by the community it supports.
In order to get the most of out it, it is recommended to run it in your CI environment. When set up like this, the workflow involves four steps. It all starts when a developer commits new code from the Looker IDE (Step 1). GitHub then sends off a webhook to the server hosting LAMS asking it to check the new code (Step 2). Once LAMS does this, it adds the result files to the trigger branch (Step 3) and the user will be prompted to pull the files from his remote branch (Step 4). The entire process takes a few seconds at most and is entirely seamless, providing everything that the developer needs from within the platform.
LAMS can be installed either as a standalone npm package using these instructions or deployed in your CI environment. The latter is highly recommended but since it can be quite an involved process, we are also shipping it with a dockerized version that contains a fully functional Jenkins server with a pre-configured job. This will allow you to get setup in just a few minutes and hit the ground running. If you want to contribute to the project, check it out on github.
LAMS is developed and maintained by Fabio Beltramini (aka @fabio1 ) and Joseph Axisa (aka @jax1 )
Hey @fabio1 this is super helpful! We are trying to implement this with some custom rules. I was using your example
($boolean ($match
"^Is |^Has "
::match:label
))
and trying something similar, namely to setup a rule that checks whether booleans (dimensions of type: yesno) start with âisâ or âhasâ in the name. I used the following syntax, but it doesnât seem to recognize boolean dimensions, the output shows errors of all dimensions of all types, but I only want to apply it on dimensions that have type: yesno (so booleans). So not sure what $boolean does in the example syntax.
LAMS
rule: boolean_name {
description: âBoolean dimensions must start with is or hasâ
To start, Iâll clarify the existing example. The expressions translate to JavaScript for execution and use its underlying type system. $match corresponds to the String.prototype.match method, which can return an array for a successful match or null for a failed match. The purpose here of the $boolean function is to coerce these values into true/false, which are acceptable results for a LAMS custom rule expression. (A few other types are acceptable, including strings for custom error messages)
Here are three different ways you could apply this expression to yesno dimensions:
#rule: F_yn1 {
description: âDimensons of type:yesno must be labeled starting with Is or Hasâ
The first approach is nice in that is actually restricts the number of matches, which can make the summary statistics seem more representative. However, the property-based selection can be limiting, so sometimes you have to fall back to a more general approach of matching all fields and applying an $if statement inside the rule expression.
PS. In case you missed it, one convenient way to test things out is the Rule Sandbox
Hey @fabio1 thanks a lot for your reply, super helpful! I understand the purpose of the $boolean now. I tried to use the example but strange thing is it doesnât seem to work if I use the dimension parameter. Letâs say I have this example dimension in a view:
Iâm not sure if Iâm doing something wrong or how it does work for the label parameter but not for the dimension parameter, would you have any idea? Thanks in advance
Hey @anique_trip-163 , sorry for the confusion, when I wrote the examples, I just tested them partially.. they will always error for type yesno dimensions, because I left the reference to ::match:dimension unchanged. This would only make sense if there were a property named dimension under the matched dimension.
You have figured it out well with the label property, and often that is what people want because Is/Has dimension labels should end with a â?â, so an explicit label is required.
However, if you wanted to accept an is_/has_ field name, with no label, you can use the $name property that is added to the dimension, referred to in the expression by ::match:$name
You could accept either one like this⌠I didnât test this, but hopefully I wrote it correctly
LAMS
rule: F_yn {
description: âDimensions of type:yesno must have a label starting with Is or Hasâ
Hey @fabio1 ah great this worked! I needed the $name property for the actual name of the dimension or measure. I tested it and it works now, so thanks a lot for the explanation!
Hey @fabio1 nice stuff! We are trying to set this up in our Gitlab CI. Iâm using the below .gitlab-ci.yml file and added this in our Looker project. It seems like this checks the rules on all the existing LookML files in the project, however we only want to apply it to files that are being changed in the commit/branch, and not on all existing/previously built LookML code. Would you know how we could set this up so that it only checks for actual changed files in the commit/branch? That would be super helpful!
First, a bit of background about our Gitlab CI example configuration. It was contributed by members of the community while LAMS was in v1. Between v1 â v2, LAMSâ default output mode changed. It seems like you are already adapting the commands a bit, so hopefully it works for you. If so, perhaps consider sending along a PR to update our Gitlab CI example doc, as I am not familiar enough with the conventions and best practices around the artifacts concept used by Gitlab CI.
As for your question about linting changed files⌠a lot of LAMS users have ended up doing something like this over the years, using git to identify changed files, and passing this to LAMSâ source argument. However, I always found the approach of diff-then-lint to be lacking. For one, file-level granularity is very coarse, but more importantly it fails to handle things like extensions/refinements/includes which may compose LookML across multiple files, some of which may be unmodified. Thatâs why in v3.1-,v3.1,-This%20update%20introduces), released last week, I introduced incremental linting as a native feature (in beta). Take a look at that, and let me know whether it works for your needs/use case. The feature is still open to changes based on community feedback!
Hey @fabio1 thanks for your reply! What do you mean with incremental linting was released in v3.1, how would incremental linting work exactly? Would that work similar to changed files? And when could this feature be live in production to start using? Curious to hear more! Thanks, Anique
Hi Anique! The idea behind this feature is that if at any point (for example, once manually, or upon merging a set of changes), you wish to exempt all current errors in future runs, you can run LAMS with --output=add-exemptions and check in the resulting/updated lams-exemptions.ndjson file to your repo. On subsequent runs, all those errors would be exempt, and so the reported errors would just be the new/incremental ones.
I would love to chat with you to understand if this works for your needs, or to better understand how you would configure this in Gitlab CI, so if youâre interested in setting up a call net week, shoot me an email at (PII Removed by Staff)
Hi @borysarkhypenko - Iâm glad youâre finding value in LAMS. Iâm not 100% sure of the cause, but for starters, I notice that you only have a single hyphen to start this argument, whereas the convention is two hyphens.
-output=add-exemptions
If you are still having trouble, feel free to open an issue on the Github repoâs issue tracker, as I follow that as well, and it can be a bit more organized to keep things in one issue thread.
Also, lams-exemptions.nsdjon is stored/found in the working directory where you executed LAMS. This is by default the same as the LookML project root, though it may be different if you invoke LAMS to intentionally change that.