Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thoughts on folded text block? #915

Open
drewgingerich opened this issue Jun 1, 2021 · 4 comments
Open

Thoughts on folded text block? #915

drewgingerich opened this issue Jun 1, 2021 · 4 comments

Comments

@drewgingerich
Copy link

drewgingerich commented Jun 1, 2021

This is cross-posted at google/go-jsonnet.

YAML has folded-style multi-line strings, which means that new-lines are replaced with spaces to end up with a single-line string. I find this convenient for splitting long shell commands over multiple lines for readability. Does this seem like something potentially good to implement?

I know that jsonnet has the ||| text block but this does not replace newlines, behaving like a "literal" instead of "folded" YAML multi-line string. Syntax for a "folded" text block in jsonnet could be an extension of the text block syntax: e.g. |||>.

For example and context, I'm looking at using jsonnet to produce YAML Gitlab CI config files. By hand a simplified version looks like this:

build:
  stage: build
  only:
    - main
  image: my.kaniko.image
  script:
    - init-kaniko
    - >-
      /kaniko/executor
      --context .
      --dockerfile Dockerfile
      --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
      --destination $CI_REGISTRY_IMAGE:latest

To reproduce this in jsonnet I need to use a function to replace the newlines:

local folded_text_block(text_block) = std.strReplace(text_block, '\n', ' ');

{
  build: {
    stage: 'build',
    only: ['main'],
    image: 'my.kaniko.image',
    script: [
      'init-kaniko',
      folded_text_block(
        |||
          /kaniko/executor
          --context .
          --dockerfile Dockerfile
          --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
          --destination $CI_REGISTRY_IMAGE:latest
        |||
      ),
    ],
  },
}

Whereas with a builtin folded text block (using my made-up syntax from above) I could do:

{
  build: {
    stage: 'build',
    only: ['main'],
    image: 'my.kaniko.image',
    script: [
      'init-kaniko',
      |||>
        /kaniko/executor
        --context .
        --dockerfile Dockerfile
        --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
        --destination $CI_REGISTRY_IMAGE:latest
      |||,
    ],
  },
}

The "long line" in the above example is also pretty tame and could be squished into a single line. Some commands are far longer and simply must be split over multiple lines for readability, and I think a "folded" text block could make these easy handle.

This is a small deal in the scheme of things. I get a lot of joy from the flexibility of YAML's multi-line strings and would love to see some of it in jsonnet.

@sbarzowski
Copy link
Collaborator

Are you aware of ||| text blocks? See the tutorial: https://jsonnet.org/learning/tutorial.html.

@drewgingerich
Copy link
Author

drewgingerich commented Jun 2, 2021

Hi @sbarzowski I did see the ||| text block, but I did not see a way to replace the newlines with it. I've done this with a small function, but I like the terseness and flow of the YAML folded-style multi-line string for long shell commands.

I've updated the question to better describe what I'm talking about related to the current ||| text block.

@sbarzowski
Copy link
Collaborator

Ah, so you want the newlines replaced with spaces. I see how it can be quite useful sometimes.

@zc-devs
Copy link

zc-devs commented Oct 29, 2024

Hi,
I use >- folded style with chomping indicator for writing CSP headers in Traefik middleware:

apiVersion: traefik.io/v1alpha1
kind: Middleware
spec:
  headers:
    contentSecurityPolicy: >-
      upgrade-insecure-requests;
      base-uri 'self';
      default-src 'self';

Example above works great.
Recently, I've migrated to Grafana Tanka and that snippet was replaced by:

      middlewareHeaders:
        local mw = traefik.middleware;
        mw.new(fullName + '-headers', namespace)
        + mw.metadata.withLabels(labels)
        + mw.spec.headers.withContentSecurityPolicy(|||
          upgrade-insecure-requests;
          base-uri 'self';
          default-src 'self';
        |||),

which renders into

    contentSecurityPolicy: |
      upgrade-insecure-requests;
      base-uri 'self';
      default-src 'self';

While std.stripChars can convert | to |-, it will be multi-line string anyway. Therefore, it doesn't work as HTTP header.
As a workaround I can replace line endings

        + mw.spec.headers.withContentSecurityPolicy(std.strReplace(|||
          upgrade-insecure-requests;
          base-uri 'self';
          default-src 'self';
        |||, '\n', ' ')),

and it would be rendered as

    contentSecurityPolicy: 'upgrade-insecure-requests; base-uri ''self''; default-src
      ''none''; form-action ''none''; frame-ancestors ''none''; '

which works, but looks ugly.
So, it would be nice to have ability to render multi-line block as folded YAML, whether it would be addition to||| or some standard function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
@sbarzowski @drewgingerich @zc-devs and others