Skip to content

Commit

Permalink
Add NOTHING action
Browse files Browse the repository at this point in the history
This is a proposal for a change that allows you to leave the `action`
column blank to signify that you want the rule to match messages and
stop processing further rules, but not actually move the thread from
its current state (similar to the current `mark_important` column
behavior).

I'm having trouble correctly routing code review emails. I don't want CI
messages for other people's changes to move threads to my inbox, but if
I specify `archive` on those, and a CI message is processed in the same
run as a relevant message, it overrides the relevant message. I could
move the CI filter rule below, but that precludes a "catch-all" review
rule to route uncategorized reviews to my inbox.

If this seems OK, let me know and I can add tests and make it a nicer
thing.
  • Loading branch information
aaronj1335 committed Aug 26, 2024
1 parent 37b828f commit b060508
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
3 changes: 2 additions & 1 deletion Processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ export class Processor {
break;
}
if (rule.condition.match(message_data)) {
console.log(`rule ${rule} matches message ${message_data}, apply action ${rule.thread_action}`);
console.log(`Rule ${rule} matches message ${message_data}, apply action ${rule.thread_action}`);
thread_data.thread_action.mergeFrom(rule.thread_action);
console.log(`Thread action after merging: ${thread_data.thread_action}`)
let endThread = false;
switch (rule.thread_action.action_after_match) {
case ActionAfterMatchType.DONE:
Expand Down
2 changes: 1 addition & 1 deletion Rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class Rule {

private static parseInboxActionType(str: string): InboxActionType {
if (str.length === 0) {
return InboxActionType.DEFAULT;
return InboxActionType.NOTHING;
}
const result = InboxActionType[str.toUpperCase() as keyof typeof InboxActionType];
Utils.assert(result !== undefined, `Can't parse inbox action value ${str}.`);
Expand Down
46 changes: 42 additions & 4 deletions ThreadAction.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
import ThreadAction from './ThreadAction';
import ThreadAction, {InboxActionType} from './ThreadAction';
import Utils from './utils';

describe('ThreadAction Tests', () => {
ThreadAction.testThreadActions(it, expect);
})
it('Adds parent labels', () => {
const labels = ['list/abc', 'bot/team1/test', 'bot/team1/alert', 'def'];
const action = new ThreadAction();
const expected = new Set(['list', 'list/abc', 'bot', 'bot/team1', 'bot/team1/test', 'bot/team1/alert', 'def'])

action.addLabels(labels);

Utils.assert(action.label_names.size === expected.size,
`Expected ${Array.from(expected).join(', ')},
but got ${Array.from(action.label_names).join(', ')}`);

for (const label of expected) {
Utils.assert(action.label_names.has(label), `Expected label ${label}, but not present in action.`);
}
});

it('Does not add parent labels for empty list', () => {
const labels: string[] = [];
const action = new ThreadAction();

action.addLabels(labels);

Utils.assert(action.label_names.size === 0,
`Expected empty set, but got ${Array.from(action.label_names).join(', ')}`);
});

it('Correctly merges NOTHING actions', () => {
const thread_data_action = new ThreadAction();
const rule_action = new ThreadAction();
rule_action.move_to = InboxActionType.NOTHING;

Utils.assert(thread_data_action.move_to == InboxActionType.DEFAULT,
`move_to should be DEFAULT, but is ${thread_data_action.move_to}`);
thread_data_action.mergeFrom(rule_action);

Utils.assert(thread_data_action.move_to == InboxActionType.NOTHING,
`move_to should be NOTHING, but is ${thread_data_action.move_to}`);
Utils.assert(rule_action.toString() == '>NOTHING +L',
`rule_action should be '>NOTHING +L', but is ${rule_action}`);
});
2 changes: 1 addition & 1 deletion ThreadAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

export enum BooleanActionType {DEFAULT, ENABLE, DISABLE}

export enum InboxActionType {DEFAULT, INBOX, ARCHIVE, TRASH}
export enum InboxActionType {DEFAULT, INBOX, ARCHIVE, TRASH, NOTHING}

export enum ActionAfterMatchType {DEFAULT, DONE, FINISH_STAGE, NEXT_STAGE}

Expand Down
6 changes: 3 additions & 3 deletions ThreadData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,19 @@ export class ThreadData {
}

validateActions() {
if (!this.thread_action.hasAnyAction()) {
if (!this.thread_action.hasAnyAction() && this.thread_action.move_to != InboxActionType.NOTHING) {
const messages = this.raw.getMessages();
const last_message = messages[messages.length - 1];
const from = last_message.getFrom();
const to = last_message.getTo();
throw `Thread "${this.raw.getFirstMessageSubject()}" from ${from} to ${to} has no action, does it match any rule?`;
throw `Thread "${this.raw.getFirstMessageSubject()}" from ${from} to ${to} has default action (${this.thread_action}), does it match any rule?`;
}
}

static applyAllActions(session_data: SessionData, all_thread_data: ThreadData[]) {
const label_action_map: { [key: string]: GoogleAppsScript.Gmail.GmailThread[] } = {};
const moving_action_map = new Map<InboxActionType, GoogleAppsScript.Gmail.GmailThread[]>([
[InboxActionType.DEFAULT, []], [InboxActionType.INBOX, []], [InboxActionType.ARCHIVE, []], [InboxActionType.TRASH, []]
[InboxActionType.DEFAULT, []], [InboxActionType.INBOX, []], [InboxActionType.ARCHIVE, []], [InboxActionType.TRASH, []], [InboxActionType.NOTHING, []]
]);
const important_action_map = new Map<BooleanActionType, GoogleAppsScript.Gmail.GmailThread[]>([
[BooleanActionType.DEFAULT, []], [BooleanActionType.ENABLE, []], [BooleanActionType.DISABLE, []]
Expand Down

0 comments on commit b060508

Please sign in to comment.