diff --git a/README.md b/README.md index cebdc63..68e1783 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The `# TODO` comment is commonly used in Python, but this can be customised to w - [Examples](#examples) - [Adding TODOs](#adding-todos) - [Multiline TODOs](#multiline-todos) + - [Specifying Identifier](#specifying-identifier) - [Specifying Labels](#specifying-labels) - [Specifying Assignees](#specifying-assignees) - [Specifying Milestone](#specifying-milestone) @@ -31,7 +32,7 @@ Create a workflow file in your .github/workflows directory as follows: ### workflow.yaml -Latest version is `v2.3`. +Latest version is `v2.4`. name: "Workflow" on: ["push"] @@ -41,7 +42,7 @@ Latest version is `v2.3`. steps: - uses: "actions/checkout@master" - name: "TODO to Issue" - uses: "alstr/todo-to-issue-action@v2.3" + uses: "alstr/todo-to-issue-action@v2.4" id: "todo" with: TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -56,9 +57,10 @@ Latest version is `v2.3`. | `BEFORE` | "${{ github.event.before }}" | The SHA of the last pushed commit (automatically set) | | `SHA` | "${{ github.sha }}" | The SHA of the latest commit (automatically set) | | `TOKEN` | "${{ secrets.GITHUB_TOKEN }}" | The GitHub access token to allow us to retrieve, create and update issues (automatically set) | -| `LABEL` | "# TODO" | The label that will be used to identify TODO comments (e.g. `# TODO` for Python) | -| `COMMENT_MARKER` | "#" | The marker used to signify a line comment in your code (e.g. `#` for Python) | +| `LABEL` | "# TODO" | The label that will be used to identify TODO comments | +| `COMMENT_MARKER` | "#" | The marker used to signify a line comment in your code | | `CLOSE_ISSUES` | "true" | Optional input that specifies whether to attempt to close an issue when a TODO is removed | +| `AUTO_P` | "true" | For multiline TODOs, format each line as a new paragraph when creating the issue | ## Examples @@ -91,6 +93,17 @@ The extra line(s) will be posted in the body of the issue. The `COMMENT_MARKER` input must be set to the correct syntax (e.g. `#` for Python). +Each line in the multiline TODO will be formatted as a paragraph in the issue body. To disable this, set `AUTO_P` to `"false"`. + +### Specifying Identifier + + def hello_world(): + # TODO(alstr) Come up with a more imaginative greeting + +As per the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#TODO_Comments), you can provide an identifier after the TODO label. This will be included in the issue title for searchability. + +Don't include parentheses within the identifier itself. + ### Specifying Labels def hello_world(): @@ -166,7 +179,7 @@ If you do encounter any problems, please file an issue. PRs are welcome and appr ## Thanks -Thanks to Jacob Tomlinson for [ his handy overview of GitHub Actions ](https://www.jacobtomlinson.co.uk/posts/2019/creating-github-actions-in-python/). +Thanks to Jacob Tomlinson for [his handy overview of GitHub Actions](https://www.jacobtomlinson.co.uk/posts/2019/creating-github-actions-in-python/). Thanks to GitHub's [linguist repo](https://github.com/github/linguist/) for the [ `languages.yml` ]( https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file used by the app to determine the correct highlighting to apply to code snippets. diff --git a/action.yml b/action.yml index dbcbf7c..bd03254 100644 --- a/action.yml +++ b/action.yml @@ -24,14 +24,18 @@ inputs: description: "The GitHub access token to allow us to retrieve, create and update issues (automatically set)" required: true LABEL: - description: "The label that will be used to identify TODO comments (e.g. # TODO for Python)" + description: "The label that will be used to identify TODO comments" required: true default: "# TODO" COMMENT_MARKER: - description: "The marker used to signify a line comment in your code (e.g. # for Python)" + description: "The marker used to signify a line comment in your code" required: true default: "#" CLOSE_ISSUES: - description: "Optional input that specifies whether to attempt to close an issue when a TODO is removed (default: true)" + description: "Optional input that specifies whether to attempt to close an issue when a TODO is removed" + required: false + default: "true" + AUTO_P: + description: "For multiline TODOs, format each line as a new paragraph when creating the issue" required: false default: "true" diff --git a/main.py b/main.py index cb4e304..2fc0305 100644 --- a/main.py +++ b/main.py @@ -20,7 +20,9 @@ def main(): comment_marker = os.getenv('INPUT_COMMENT_MARKER') label = os.getenv('INPUT_LABEL') token = os.getenv('INPUT_TOKEN') - close_issues = os.getenv('INPUT_CLOSE_ISSUES') + close_issues = os.getenv('INPUT_CLOSE_ISSUES') == 'true' + auto_p = os.getenv('AUTO_P') == 'true' + line_break = '\n\n' if auto_p else '\n' # Load a file so we can see what language each file is written in and apply highlighting later. languages_url = 'https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml' @@ -69,7 +71,9 @@ def get_current_issues(page=1): line_num_pattern = re.compile(r'(?<=\+).+') addition_pattern = re.compile(r'(?<=^\+).*') deletion_pattern = re.compile(r'(?<=^-).*') - todo_pattern = re.compile(r'(?<=' + label + r'[\s:]).+') + todo_pattern = re.compile(r'(?<=' + label + r'[(\s:]).+') + identifier_pattern = re.compile(r'.+(?=\))') + title_pattern = re.compile(r'(?<=\)[\s:]).+') comment_pattern = re.compile(r'(?<=' + comment_marker + r'\s).+') labels_pattern = re.compile(r'(?<=labels:).+') assignees_pattern = re.compile(r'(?<=assignees:).+') @@ -90,6 +94,9 @@ def get_current_issues(page=1): # If True, the current issue is updated with the extra details from this line. def process_line(next_line): if previous_line_was_todo: + if next_line.strip() == comment_marker: + curr_issue['body'] += line_break + return True comment_search = comment_pattern.search(next_line) if comment_search: comment = comment_search.group(0).lstrip() @@ -111,7 +118,7 @@ def process_line(next_line): if milestone.isdigit(): curr_issue['milestone'] = int(milestone) else: - curr_issue['body'] += '\n\n' + comment_search.group(0).lstrip() + curr_issue['body'] += line_break + comment return True return False @@ -150,6 +157,15 @@ def process_line(next_line): # A new item was found. Start recording so we can capture multiline TODOs. previous_line_was_todo = True todo = todo_search.group(0).lstrip() + identifier_search = identifier_pattern.search(todo) + title_search = title_pattern.search(todo) + if identifier_search and title_search: + todo = f'[{identifier_search.group(0)}] {title_search.group(0).lstrip()}' + elif identifier_search: + todo = identifier_search.group(0) # Shouldn't really arise. + elif title_search: + todo = title_search.group(0) # Shouldn't really arise. + if curr_issue: curr_issue['hunk'] = lines new_issues.append(curr_issue)