mbrt/gmailctl

Add option to apply all parent labels if `gmailctl` is managing labels

Closed this issue · 4 comments

One of the most annoying things that I find about Gmail's UI for managing filters is how it handles nested labels. For my workflow, I want to be able to do the following:

  • Create a new label Foo, with a nested label called Bar. In Gmail terms, this means that labels "Foo" and "Foo/Bar" are created.
  • Define a filter that applies the nested "Foo/Bar" label.
  • Later, if I search for the label "Foo", emails related to "Bar" should show up (because it's nested - in my mind, a label of "Foo/Bar" should show results if I just look at the "Foo" label)

Unfortunately, that isn't what happens (at least, not in the Gmail interface). If all I do is specify a filter that applies the label "Foo/Bar", that email will not show up if I search for the label "Foo". I have to manually specify both labels "Foo" and "Foo/Bar" in order for that email to show up in both searches.

It would be great if it were possible to specify a "rule" in gmailctl that effectively tells the tool to "expand" the labels to apply such that, if I specify a label of "Foo/Bar", it takes care of adding both "Foo" and "Foo/Bar".

Any chance that could be done? I'm fine if this is optional, as this would change from the current implementation, but it's something I wish I could have :)

To clarify, currently in order for a nested label + its parents to be filed, I would have to do something like this:

    {
      filter: {
        from: "abc@123.com"
      },
      actions: {
        labels: [
          "Foo/Bar/Baz/Bax",
          "Foo/Bar/Baz",
          "Foo/Bar",
          "Foo",
        ]
      }
    },

When It feels like I should be able to do something like this (making up a new option):

    {
      filter: {
        from: "abc@123.com"
      },
      actions: {
        labels: [
          "Foo/Bar/Baz/Bax",
        ],
        expandLabels: true // this would imply that the `labels` array should be split on the "/" so that all labels are applied as needed
      }
    },
mbrt commented

This can be achieved by using Jsonnet directly. I'm always reluctant to add features in gmailctl itself, especially user-specific workflows. This will make it bloated and difficult to understand over time.

With that said, what you want could be achieved by using Jsonnet functions directly. I can see how a addParents function could take a label and produce an array with the same + all the parents.

actions: { labels: addParents('Foo/Bar') },

https://github.com/mbrt/gmailctl/blob/master/internal/data/gmailctl.libsonnet#L45 should serve as an inspiration for the implementation.

Ah okay, fair enough! I should dig more into what is possible with jsonnet anyway, as you said. If I come up with something, I'll be sure to share it here.

Forgot to comment - this is the solution I went with, and it's been working well:

{
  # This will take an array and transform strings like ["some/label"] to ["some", "some/label"]
  expandLabels(labels)::
    local splitLabel(label) = std.split(label, '/');
    local genSubLabels(label) =
      [
        std.join(
          '/',
          splitLabel(label)[:i + 1]
        )
        for i in std.range(0, std.length(splitLabel(label)) - 1)
      ];
    std.flattenArrays([genSubLabels(i) for i in labels]),
}