mirror of
https://github.com/ditkrg/todo-to-issue-action.git
synced 2026-01-23 06:16:43 +00:00
commit
5aa95f6c12
79
main.py
79
main.py
@ -8,6 +8,7 @@ from io import StringIO
|
||||
import itertools
|
||||
import operator
|
||||
from collections import defaultdict
|
||||
import sys
|
||||
|
||||
from Client import Client
|
||||
from GitHubClient import GitHubClient
|
||||
@ -15,24 +16,9 @@ from LineStatus import LineStatus
|
||||
from LocalClient import LocalClient
|
||||
from TodoParser import TodoParser
|
||||
|
||||
if __name__ == "__main__":
|
||||
client: Client | None = None
|
||||
# Try to create a basic client for communicating with the remote version control server, automatically initialised with environment variables.
|
||||
try:
|
||||
# try to build a GitHub client
|
||||
client = GitHubClient()
|
||||
except EnvironmentError:
|
||||
# don't immediately give up
|
||||
pass
|
||||
# if needed, fall back to using a local client for testing
|
||||
client = client or LocalClient()
|
||||
|
||||
# Get the diff from the last pushed commit.
|
||||
last_diff = client.get_last_diff()
|
||||
|
||||
if last_diff:
|
||||
def process_diff(diff, client=Client(), insert_issue_urls=False, parser=TodoParser(), output=sys.stdout):
|
||||
# Parse the diff for TODOs and create an Issue object for each.
|
||||
raw_issues = TodoParser().parse(StringIO(last_diff))
|
||||
raw_issues = parser.parse(diff)
|
||||
# This is a simple, non-perfect check to filter out any TODOs that have just been moved.
|
||||
# It looks for items that appear in the diff as both an addition and deletion.
|
||||
# It is based on the assumption that TODOs will not have identical titles in identical files.
|
||||
@ -47,7 +33,7 @@ if __name__ == "__main__":
|
||||
or (similar_issues[1].status == LineStatus.ADDED
|
||||
and similar_issues[0].status == LineStatus.DELETED))):
|
||||
print(f'Issue "{values[0]}" appears as both addition and deletion. '
|
||||
f'Assuming this issue has been moved so skipping.')
|
||||
f'Assuming this issue has been moved so skipping.', file=output)
|
||||
continue
|
||||
issues_to_process.extend(similar_issues)
|
||||
|
||||
@ -75,16 +61,13 @@ if __name__ == "__main__":
|
||||
issues_to_process = [issue for issue in issues_to_process if
|
||||
not (issue.issue_url in update_and_close_issues and issue.status == LineStatus.DELETED)]
|
||||
|
||||
# Check to see if we should insert the issue URL back into the linked TODO.
|
||||
insert_issue_urls = os.getenv('INPUT_INSERT_ISSUE_URLS', 'false') == 'true'
|
||||
|
||||
# Cycle through the Issue objects and create or close a corresponding GitHub issue for each.
|
||||
for j, raw_issue in enumerate(issues_to_process):
|
||||
print(f"Processing issue {j + 1} of {len(issues_to_process)}: '{raw_issue.title}' @ {raw_issue.file_name}:{raw_issue.start_line}")
|
||||
for j, raw_issue in enumerate(sorted(reversed(sorted(issues_to_process, key = operator.attrgetter('start_line'))), key = operator.attrgetter('file_name'))):
|
||||
print(f"Processing issue {j + 1} of {len(issues_to_process)}: '{raw_issue.title}' @ {raw_issue.file_name}:{raw_issue.start_line}", file=output)
|
||||
if raw_issue.status == LineStatus.ADDED:
|
||||
status_code, new_issue_number = client.create_issue(raw_issue)
|
||||
if status_code == 201:
|
||||
print(f'Issue created: : #{new_issue_number} @ {client.get_issue_url(new_issue_number)}')
|
||||
print(f'Issue created: #{new_issue_number} @ {client.get_issue_url(new_issue_number)}', file=output)
|
||||
# Don't insert URLs for comments. Comments do not get updated.
|
||||
if insert_issue_urls and not (raw_issue.ref and raw_issue.ref.startswith('#')):
|
||||
line_number = raw_issue.start_line - 1
|
||||
@ -92,27 +75,57 @@ if __name__ == "__main__":
|
||||
file_lines = issue_file.readlines()
|
||||
if line_number < len(file_lines):
|
||||
# Duplicate the line to retain the comment syntax.
|
||||
new_line = file_lines[line_number]
|
||||
remove = fr'{raw_issue.identifier}.*{raw_issue.title}'
|
||||
old_line = file_lines[line_number]
|
||||
remove = fr'(?i:{raw_issue.identifier}).*{re.escape(raw_issue.title)}'
|
||||
insert = f'Issue URL: {client.get_issue_url(new_issue_number)}'
|
||||
new_line = re.sub(remove, insert, new_line)
|
||||
new_line = re.sub(remove, insert, old_line)
|
||||
# make sure the above operation worked as intended
|
||||
if new_line != old_line:
|
||||
# Check if the URL line already exists, if so abort.
|
||||
if line_number == len(file_lines) - 1 or file_lines[line_number + 1] != new_line:
|
||||
file_lines.insert(line_number + 1, new_line)
|
||||
with open(raw_issue.file_name, 'w') as issue_file:
|
||||
issue_file.writelines(file_lines)
|
||||
elif status_code == 200:
|
||||
print(f'Issue updated: : #{new_issue_number} @ {client.get_issue_url(new_issue_number)}')
|
||||
print('Issue URL successfully inserted', file=output)
|
||||
else:
|
||||
print('Issue could not be created')
|
||||
print('ERROR: Issue URL was NOT successfully inserted', file=output)
|
||||
elif status_code == 200:
|
||||
print(f'Issue updated: #{new_issue_number} @ {client.get_issue_url(new_issue_number)}', file=output)
|
||||
else:
|
||||
print('Issue could not be created', file=output)
|
||||
elif raw_issue.status == LineStatus.DELETED and os.getenv('INPUT_CLOSE_ISSUES', 'true') == 'true':
|
||||
if raw_issue.ref and raw_issue.ref.startswith('#'):
|
||||
print('Issue looks like a comment, will not attempt to close.')
|
||||
print('Issue looks like a comment, will not attempt to close.', file=output)
|
||||
continue
|
||||
status_code = client.close_issue(raw_issue)
|
||||
if status_code in [200, 201]:
|
||||
print('Issue closed')
|
||||
print('Issue closed', file=output)
|
||||
else:
|
||||
print('Issue could not be closed')
|
||||
print('Issue could not be closed', file=output)
|
||||
# Stagger the requests to be on the safe side.
|
||||
sleep(1)
|
||||
|
||||
return raw_issues
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
client: Client | None = None
|
||||
# Try to create a basic client for communicating with the remote version control server, automatically initialised with environment variables.
|
||||
try:
|
||||
# try to build a GitHub client
|
||||
client = GitHubClient()
|
||||
except EnvironmentError:
|
||||
# don't immediately give up
|
||||
pass
|
||||
# if needed, fall back to using a local client for testing
|
||||
client = client or LocalClient()
|
||||
|
||||
# Get the diff from the last pushed commit.
|
||||
last_diff = client.get_last_diff()
|
||||
|
||||
# process the diff
|
||||
if last_diff:
|
||||
# Check to see if we should insert the issue URL back into the linked TODO.
|
||||
insert_issue_urls = os.getenv('INPUT_INSERT_ISSUE_URLS', 'false') == 'true'
|
||||
|
||||
process_diff(StringIO(last_diff), client, insert_issue_urls)
|
||||
|
||||
10
tests/test_comment_suffix_after_source_line.diff
Normal file
10
tests/test_comment_suffix_after_source_line.diff
Normal file
@ -0,0 +1,10 @@
|
||||
diff --git a/comment_suffix_after_source_line.c b/comment_suffix_after_source_line.c
|
||||
new file mode 100644
|
||||
index 0000000..d340f6a
|
||||
--- /dev/null
|
||||
+++ b/comment_suffix_after_source_line.c
|
||||
@@ -0,0 +1,4 @@
|
||||
+void some_func() {
|
||||
+ int x = 0; // TODO: give this a better name
|
||||
+ x++;
|
||||
+}
|
||||
14
tests/test_edit.diff
Normal file
14
tests/test_edit.diff
Normal file
@ -0,0 +1,14 @@
|
||||
diff --git a/tests/example.bas b/tests/example.bas
|
||||
index 6b0c6cf..b37e70a 100644
|
||||
--- a/tests/example.bas
|
||||
+++ b/tests/example.bas
|
||||
@@ -1,1 +1,2 @@
|
||||
+' TODO: simplify
|
||||
Public Sub MakeThingsComplicated()
|
||||
diff --git a/tests/example.frm b/tests/example.frm
|
||||
index 6b0c6cf..b37e70a 100644
|
||||
--- a/tests/example.frm
|
||||
+++ b/tests/example.frm
|
||||
@@ -1,1 +1,2 @@
|
||||
+' TODO: remove feature to prevent legal issues
|
||||
Public Sub Plagiarize()
|
||||
@ -1,8 +1,8 @@
|
||||
diff --git a/tests/ExampleFile.java b/tests/ExampleFile.java
|
||||
diff --git a/ExampleFile.java b/ExampleFile.java
|
||||
new file mode 100644
|
||||
index 0000000..d340f6a
|
||||
--- /dev/null
|
||||
+++ b/tests/ExampleFile.java
|
||||
+++ b/ExampleFile.java
|
||||
@@ -0,0 +1,13 @@
|
||||
+package com.mydomain.myapp;
|
||||
+
|
||||
@ -18,11 +18,11 @@ index 0000000..d340f6a
|
||||
+ */
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/example-file.php b/tests/example-file.php
|
||||
diff --git a/example-file.php b/example-file.php
|
||||
new file mode 100644
|
||||
index 0000000..063bb80
|
||||
--- /dev/null
|
||||
+++ b/tests/example-file.php
|
||||
+++ b/example-file.php
|
||||
@@ -0,0 +1,23 @@
|
||||
+<!DOCTYPE html>
|
||||
+<html>
|
||||
@ -48,11 +48,11 @@ index 0000000..063bb80
|
||||
+</body>
|
||||
+</html>
|
||||
\ No newline at end of file
|
||||
diff --git a/tests/example_file.py b/tests/example_file.py
|
||||
diff --git a/example_file.py b/example_file.py
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.py
|
||||
+++ b/example_file.py
|
||||
@@ -0,0 +1,23 @@
|
||||
+def hello_world():
|
||||
+ # TODO: Come up with a more imaginative greeting
|
||||
@ -78,11 +78,11 @@ index 0000000..525e25d
|
||||
+ '''
|
||||
+ pass
|
||||
\ No newline at end of file
|
||||
diff --git a/src/Swarm/Game/example.hs b/src/Swarm/Game/example.hs
|
||||
diff --git a/example.hs b/example.hs
|
||||
new file mode 100644
|
||||
index 0000000..0ce9b1a
|
||||
--- /dev/null
|
||||
+++ b/src/Swarm/Game/example.hs
|
||||
+++ b/example.hs
|
||||
@@ -0,0 +1,14 @@
|
||||
+-- | Standard devices that are always installed.
|
||||
+--
|
||||
@ -98,23 +98,23 @@ index 0000000..0ce9b1a
|
||||
+TODO: Create an issue for TODO
|
||||
+-}
|
||||
+sum a b = a + b
|
||||
diff --git a/tests/example_file.cr b/tests/example_file.cr
|
||||
diff --git a/example_file.cr b/example_file.cr
|
||||
new file mode 100644
|
||||
index 0000000..e6da2ec
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.cr
|
||||
@@ -0,0 +1,14 @@
|
||||
+++ b/example_file.cr
|
||||
@@ -0,0 +1,6 @@
|
||||
+# TODO: Come up with a more imaginative greeting
|
||||
+puts "Greetings"
|
||||
+
|
||||
+# TODO: Do even more stuff
|
||||
+# This function should probably do something more interesting
|
||||
+# labels: help wanted
|
||||
diff --git a/tests/example_file.rb b/tests/example_file.rb
|
||||
diff --git a/example_file.rb b/example_file.rb
|
||||
new file mode 100644
|
||||
index 0000000..e6da2ec
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.rb
|
||||
+++ b/example_file.rb
|
||||
@@ -0,0 +1,14 @@
|
||||
+#!/usr/bin/ruby -w
|
||||
+
|
||||
@ -130,11 +130,11 @@ index 0000000..e6da2ec
|
||||
+# TODO: Do even more stuff
|
||||
+# This function should probably do something more interesting
|
||||
+# labels: help wanted
|
||||
diff --git a/tests/example_file.yaml b/tests/example_file.yaml
|
||||
diff --git a/example_file.yaml b/example_file.yaml
|
||||
new file mode 100644
|
||||
index 0000000..6397789
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.yaml
|
||||
+++ b/example_file.yaml
|
||||
@@ -0,0 +1,7 @@
|
||||
+name: "TODO to Issue"
|
||||
+# TODO: Write a more interesting description
|
||||
@ -143,11 +143,11 @@ index 0000000..6397789
|
||||
+# TODO: Define inputs
|
||||
+# Need to do this before the action is released
|
||||
+# labels: urgent
|
||||
diff --git a/tests/example_file.toml b/tests/example_file.toml
|
||||
diff --git a/example_file.toml b/example_file.toml
|
||||
new file mode 100644
|
||||
index 0000000..6397789
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.toml
|
||||
+++ b/example_file.toml
|
||||
@@ -0,0 +1,7 @@
|
||||
+name = "TODO to Issue"
|
||||
+# TODO: Write a more interesting description
|
||||
@ -156,31 +156,31 @@ index 0000000..6397789
|
||||
+# TODO: Define inputs
|
||||
+# Need to do this before the action is released
|
||||
+# labels: urgent
|
||||
diff --git a/tests/example_file.prog.abap b/src/tests/example_file.prog.abap
|
||||
diff --git a/example_file.prog.abap b/example_file.prog.abap
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.prog.abap
|
||||
+++ b/example_file.prog.abap
|
||||
@@ -0,0 +1,5 @@
|
||||
+REPORT ztest_todo_2.
|
||||
+
|
||||
+DATA moo TYPE i VALUE 2.
|
||||
+WRITE moo. " TODO This is an end-of-line to-do
|
||||
+moo = 4. * TODO This is another end-of-line to-do
|
||||
diff --git a/tests/example_file.sql b/src/tests/example_file.sql
|
||||
diff --git a/example_file.sql b/example_file.sql
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.sql
|
||||
+++ b/example_file.sql
|
||||
@@ -0,0 +1,2 @@
|
||||
+-- TODO Select all:
|
||||
+SELECT * FROM Products;
|
||||
diff --git a/tests/example_file.tex b/src/tests/example_file.tex
|
||||
diff --git a/example_file.tex b/example_file.tex
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.tex
|
||||
@@ -0,0 +1,2 @@
|
||||
+++ b/example_file.tex
|
||||
@@ -0,0 +1,7 @@
|
||||
+% TODO Add in preamble details
|
||||
+\begin{document}
|
||||
+ \begin{comment}
|
||||
@ -188,24 +188,24 @@ index 0000000..7cccc5b
|
||||
+ label: urgent
|
||||
+ \end{comment}
|
||||
+\end{document}
|
||||
diff --git a/tests/example_file.jl b/src/tests/example_file.jl
|
||||
diff --git a/example_file.jl b/example_file.jl
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.jl
|
||||
@@ -0,0 +1,2 @@
|
||||
+++ b/example_file.jl
|
||||
@@ -0,0 +1,6 @@
|
||||
+ # TODO: Hopefully this comment turns into an issue
|
||||
+ print("Hello World")
|
||||
+ #= TODO: Multiline comments
|
||||
+ also need to be turned into task, and hopefully
|
||||
+ kept together as one.
|
||||
+ =#
|
||||
diff --git a/tests/defs.bzl b/tests/defs.bzl
|
||||
diff --git a/defs.bzl b/defs.bzl
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/defs.bzl
|
||||
@@ -0,0 +1,23 @@
|
||||
+++ b/defs.bzl
|
||||
@@ -0,0 +1,8 @@
|
||||
+def hello_world():
|
||||
+ # TODO: Come up with a more imaginative greeting
|
||||
+ print('Hello world')
|
||||
@ -214,12 +214,12 @@ index 0000000..525e25d
|
||||
+ # This function should probably do something more interesting
|
||||
+ # labels: help wanted
|
||||
+ pass
|
||||
diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel
|
||||
diff --git a/BUILD.bazel b/BUILD.bazel
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/BUILD.bazel
|
||||
@@ -0,0 +1,23 @@
|
||||
+++ b/BUILD.bazel
|
||||
@@ -0,0 +1,8 @@
|
||||
+def hello_world():
|
||||
+ # TODO: Come up with a more imaginative greeting
|
||||
+ print('Hello world')
|
||||
@ -228,33 +228,33 @@ index 0000000..525e25d
|
||||
+ # This function should probably do something more interesting
|
||||
+ # labels: help wanted
|
||||
+ pass
|
||||
diff --git a/tests/example_file.ahk b/src/tests/example_file.ahk
|
||||
diff --git a/example_file.ahk b/example_file.ahk
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.ahk
|
||||
+++ b/example_file.ahk
|
||||
@@ -0,0 +1,2 @@
|
||||
+ ; TODO: Find a better way to manage hotkeys
|
||||
+ ; Maybe just switch to vim??
|
||||
+ #h::
|
||||
+ RegRead, HiddenFiles_Status, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, Hidden
|
||||
diff --git a/tests/example_file.hbs b/src/tests/example_file.hbs
|
||||
diff --git a/example_file.hbs b/example_file.hbs
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.hbs
|
||||
@@ -0,0 +1,2 @@
|
||||
+++ b/example_file.hbs
|
||||
@@ -0,0 +1,5 @@
|
||||
+ <!-- TODO: Hopefully this comment turns into a todo issue -->
|
||||
+ {{!
|
||||
+ TODO: Make a handlebar templtate
|
||||
+ This is really just a test, but hopefully this works~!
|
||||
+ }}
|
||||
diff --git a/tests/example_file.org b/src/tests/example_file.org
|
||||
diff --git a/example_file.org b/example_file.org
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.org
|
||||
@@ -0,0 +1,2 @@
|
||||
+++ b/example_file.org
|
||||
@@ -0,0 +1,9 @@
|
||||
+ # TODO: Hopefully this comment turns into a todo issue
|
||||
+ #+begin_src python
|
||||
+ print("Hello World")
|
||||
@ -264,11 +264,11 @@ index 0000000..7cccc5b
|
||||
+ also need to be turned into todos, and hopefully
|
||||
+ kept together as one todo
|
||||
+ #+end_comment
|
||||
diff --git a/tests/example_file.scss b/src/tests/example_file.scss
|
||||
diff --git a/example_file.scss b/example_file.scss
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.scss
|
||||
+++ b/example_file.scss
|
||||
@@ -0,0 +1,11 @@
|
||||
+// TODO: Hopefully this comment turns into a todo issue
|
||||
+.my-class {
|
||||
@ -281,11 +281,11 @@ index 0000000..7cccc5b
|
||||
+ text-align: center;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/tests/example_file.twig b/src/tests/example_file.twig
|
||||
diff --git a/example_file.twig b/example_file.twig
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.twig
|
||||
+++ b/example_file.twig
|
||||
@@ -0,0 +1,6 @@
|
||||
+ {# TODO: Hopefully this comment turns into a todo issue #}
|
||||
+ {#
|
||||
@ -293,11 +293,11 @@ index 0000000..7cccc5b
|
||||
+ also need to be turned into todos, and hopefully
|
||||
+ kept together as one todo
|
||||
+ #}
|
||||
diff --git a/tests/example_file.md b/src/tests/example_file.md
|
||||
diff --git a/example_file.md b/example_file.md
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.md
|
||||
+++ b/example_file.md
|
||||
@@ -0,0 +1,7 @@
|
||||
+ {/* TODO: Hopefully this comment turns into a todo issue */}
|
||||
+ {/*
|
||||
@ -306,11 +306,11 @@ index 0000000..7cccc5b
|
||||
+ kept together as one todo
|
||||
+ */}
|
||||
+ - [ ] TODO: An inline todo that's NOT a comment (what)
|
||||
diff --git a/tests/example_file.mdx b/src/tests/example_file.mdx
|
||||
diff --git a/example_file.mdx b/example_file.mdx
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.mdx
|
||||
+++ b/example_file.mdx
|
||||
@@ -0,0 +1,7 @@
|
||||
+ {/* TODO: Hopefully this comment turns into a todo issue */}
|
||||
+ {/*
|
||||
@ -319,12 +319,12 @@ index 0000000..7cccc5b
|
||||
+ kept together as one todo
|
||||
+ */}
|
||||
+ - [ ] TODO: An inline todo that's NOT a comment (what)
|
||||
diff --git a/tests/example_file.r b/tests/example_file.r
|
||||
diff --git a/example_file.r b/example_file.r
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.r
|
||||
@@ -0,0 +1,23 @@
|
||||
+++ b/example_file.r
|
||||
@@ -0,0 +1,8 @@
|
||||
+hello_world <- function() {
|
||||
+ # TODO: Come up with a more imaginative greeting
|
||||
+ message("Hello world")
|
||||
@ -333,56 +333,25 @@ index 0000000..525e25d
|
||||
+ # This function should probably do something more interesting
|
||||
+ # labels: help wanted
|
||||
+}
|
||||
diff --git a/tests/example_file.rmd b/src/tests/example_file.rmd
|
||||
diff --git a/example_file.rmd b/example_file.rmd
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.rmd
|
||||
+++ b/example_file.rmd
|
||||
@@ -0,0 +0,1 @@
|
||||
+<!-- TODO: Check RMarkdown comments work -->
|
||||
diff --git a/tests/example_file.qmd b/src/tests/example_file.qmd
|
||||
diff --git a/example_file.qmd b/example_file.qmd
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/src/tests/example_file.qmd
|
||||
+++ b/example_file.qmd
|
||||
@@ -0,0 +0,1 @@
|
||||
+<!-- TODO: Check RMarkdown comments work -->
|
||||
diff --git a/tests/config.jsonc b/tests/config.jsonc
|
||||
diff --git a/example.clj b/example.clj
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/config.jsonc
|
||||
@@ -0,0 +0,11 @@
|
||||
+{
|
||||
+ "myConfig": [
|
||||
+ /*
|
||||
+ GitRepository where 'Git release/tag'
|
||||
+ matches 'Helm' version
|
||||
+ */
|
||||
+ "itIsWonderful",
|
||||
+ // TODO: Delete this line from the codebase
|
||||
+ "butItHasSomePendingActivities"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/tests/config.json5 b/tests/config.json5
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/config.json5
|
||||
@@ -0,0 +0,8 @@
|
||||
+{
|
||||
+ "myConfig": [
|
||||
+ // GitRepository where 'Git release/tag' matches 'Helm' version
|
||||
+ "itIsWonderful",
|
||||
+ // TODO: Delete this line from the codebase
|
||||
+ "butItHasSomePendingActivities"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/tests/example.clj b/tests/example.clj
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/example.clj
|
||||
+++ b/example.clj
|
||||
@@ -0,0 +1,8 @@
|
||||
+(ns example)
|
||||
+
|
||||
@ -392,22 +361,22 @@ index 0000000..525e25d
|
||||
+ ;; TODO: todo with description (sub-level)
|
||||
+ ;; Body of the issue should stay here
|
||||
+ (str "hello" name))
|
||||
diff --git a/tests/example.gd b/tests/example.gd
|
||||
diff --git a/example.gd b/example.gd
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/tests/example.gd
|
||||
+++ b/example.gd
|
||||
@@ -0,0 +1,5 @@
|
||||
+# TODO Store all the players here
|
||||
+var _players: = []
|
||||
+
|
||||
+# TODO Play the level music
|
||||
+export: var music_path: String
|
||||
diff --git a/tests/example.nix b/tests/example.nix
|
||||
diff --git a/example.nix b/example.nix
|
||||
new file mode 100644
|
||||
index 0000000..a6c6cb0
|
||||
--- /dev/null
|
||||
+++ b/tests/example.nix
|
||||
+++ b/example.nix
|
||||
@@ -0,0 +1,11 @@
|
||||
+{
|
||||
+ # TODO add missing devices
|
||||
@ -420,36 +389,22 @@ index 0000000..a6c6cb0
|
||||
+ */
|
||||
+ sum = a: b: a + b;
|
||||
+}
|
||||
diff --git a/tests/example.xaml b/tests/example.xaml
|
||||
diff --git a/example.xaml b/example.xaml
|
||||
new file mode 100644
|
||||
index 0000000..a6c6cb0
|
||||
--- /dev/null
|
||||
+++ b/tests/example.xaml
|
||||
+++ b/example.xaml
|
||||
@@ -0,0 +1,4 @@
|
||||
+<!-- TODO: Add xaml support -->
|
||||
+<Label Text="why"/>
|
||||
+<!-- TODO: please -->
|
||||
+<Label Text="ok"/>
|
||||
diff --git a/tests/example.bas b/tests/example.bas
|
||||
index 6b0c6cf..b37e70a 100644
|
||||
--- a/tests/example.bas
|
||||
+++ b/tests/example.bas
|
||||
@@ -1,1 +1,2 @@
|
||||
+' TODO: simplify
|
||||
Public Sub MakeThingsComplicated()
|
||||
diff --git a/tests/example.frm b/tests/example.frm
|
||||
index 6b0c6cf..b37e70a 100644
|
||||
--- a/tests/example.frm
|
||||
+++ b/tests/example.frm
|
||||
@@ -1,1 +1,2 @@
|
||||
+' TODO: remove feature to prevent legal issues
|
||||
Public Sub Plagiarize()
|
||||
diff --git a/tests/example.cu b/tests/example.cu
|
||||
diff --git a/example.cu b/example.cu
|
||||
new file mode 100644
|
||||
index 0000000..a6c6cb0
|
||||
--- /dev/null
|
||||
+++ b/tests/example.cu
|
||||
@@ -1,3 +1,11 @@
|
||||
+++ b/example.cu
|
||||
@@ -0,0 +1,8 @@
|
||||
+
|
||||
+// TODO rename this function
|
||||
+__global__ void test() {
|
||||
@ -458,11 +413,11 @@ index 0000000..a6c6cb0
|
||||
+ */
|
||||
+}
|
||||
+
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
diff --git a/Makefile b/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..2996176
|
||||
--- /dev/null
|
||||
+++ b/tests/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -0,0 +1,12 @@
|
||||
+# TODO change name.
|
||||
+NAME = asm
|
||||
@ -476,11 +431,11 @@ index 0000000..2996176
|
||||
+ # TODO create the directory.
|
||||
+ $(AR) rc $@ $(OBJ)
|
||||
+
|
||||
diff --git a/tests/example_file.liquid b/tests/example_file.liquid
|
||||
diff --git a/example_file.liquid b/example_file.liquid
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.liquid
|
||||
+++ b/example_file.liquid
|
||||
@@ -0,0 +1,11 @@
|
||||
+{% comment %} TODO: remove loop logic {% endcomment %}
|
||||
+{% for i in (1..3) -%}
|
||||
@ -493,11 +448,11 @@ index 0000000..7cccc5b
|
||||
+{% assign featured_product = all_products["product_handle"] %}
|
||||
+{% render "product", product: featured_product %}
|
||||
+{% endcomment %}
|
||||
diff --git a/tests/example_file.tsx b/tests/example_file.tsx
|
||||
diff --git a/example_file.tsx b/example_file.tsx
|
||||
new file mode 100644
|
||||
index 0000000..7cccc5b
|
||||
--- /dev/null
|
||||
+++ b/tests/example_file.tsx
|
||||
+++ b/example_file.tsx
|
||||
@@ -0,0 +1,13 @@
|
||||
+// TODO: rename component
|
||||
+export default async function Component() {
|
||||
@ -512,11 +467,11 @@ index 0000000..7cccc5b
|
||||
+ </div>
|
||||
+ );
|
||||
+}
|
||||
diff --git a/src/Swarm/Game/example.purs b/src/Swarm/Game/example.purs
|
||||
diff --git a/example.purs b/example.purs
|
||||
new file mode 100644
|
||||
index 0000000..0ce9b1a
|
||||
--- /dev/null
|
||||
+++ b/src/Swarm/Game/example.purs
|
||||
+++ b/example.purs
|
||||
@@ -0,0 +1,14 @@
|
||||
+-- | Standard devices that are always installed.
|
||||
+--
|
||||
@ -532,11 +487,11 @@ index 0000000..0ce9b1a
|
||||
+TODO: Create an issue for TODO
|
||||
+-}
|
||||
+sum a b = a + b
|
||||
diff --git a/src/Swarm/Game/example.agda b/src/Swarm/Game/example.agda
|
||||
diff --git a/example.agda b/example.agda
|
||||
new file mode 100644
|
||||
index 0000000..0ce9b1a
|
||||
--- /dev/null
|
||||
+++ b/src/Swarm/Game/example.agda
|
||||
+++ b/example.agda
|
||||
@@ -0,0 +1,14 @@
|
||||
+-- | Standard devices that are always installed.
|
||||
+--
|
||||
@ -569,17 +524,17 @@ index 0000000..0ce9b1a
|
||||
+ labels: urgent
|
||||
+--]]
|
||||
+local b = 2
|
||||
diff --git a/tests/Counter.sol b/tests/Counter.sol
|
||||
diff --git a/Counter.sol b/Counter.sol
|
||||
new file mode 100644
|
||||
index 0000000..d340f6a
|
||||
--- /dev/null
|
||||
+++ b/src/Counter.sol
|
||||
+++ b/Counter.sol
|
||||
@@ -0,0 +1,20 @@
|
||||
+contract Counter {
|
||||
+ // TODO: Test this
|
||||
+ // Do it
|
||||
+ // labels: urgent
|
||||
|
||||
+
|
||||
+ /// TODO: Natspec comment
|
||||
+ /// Do it
|
||||
+ /// labels: urgent
|
||||
@ -589,7 +544,7 @@ index 0000000..d340f6a
|
||||
+ Do it ASAP
|
||||
+ labels: urgent
|
||||
+ */
|
||||
|
||||
+
|
||||
+ /**
|
||||
+ * TODO: And this too
|
||||
+ * labels: urgent
|
||||
|
||||
31
tests/test_new2.diff
Normal file
31
tests/test_new2.diff
Normal file
@ -0,0 +1,31 @@
|
||||
diff --git a/config.jsonc b/config.jsonc
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/config.jsonc
|
||||
@@ -0,0 +0,11 @@
|
||||
+{
|
||||
+ "myConfig": [
|
||||
+ /*
|
||||
+ GitRepository where 'Git release/tag'
|
||||
+ matches 'Helm' version
|
||||
+ */
|
||||
+ "itIsWonderful",
|
||||
+ // TODO: Delete this line from the codebase
|
||||
+ "butItHasSomePendingActivities"
|
||||
+ ]
|
||||
+}
|
||||
diff --git a/config.json5 b/config.json5
|
||||
new file mode 100644
|
||||
index 0000000..525e25d
|
||||
--- /dev/null
|
||||
+++ b/config.json5
|
||||
@@ -0,0 +0,8 @@
|
||||
+{
|
||||
+ "myConfig": [
|
||||
+ // GitRepository where 'Git release/tag' matches 'Helm' version
|
||||
+ "itIsWonderful",
|
||||
+ // TODO: Delete this line from the codebase
|
||||
+ "butItHasSomePendingActivities"
|
||||
+ ]
|
||||
+}
|
||||
110
tests/test_process_diff.py
Normal file
110
tests/test_process_diff.py
Normal file
@ -0,0 +1,110 @@
|
||||
import json
|
||||
import os
|
||||
import unittest
|
||||
import tempfile
|
||||
import subprocess
|
||||
import io
|
||||
import re
|
||||
|
||||
from TodoParser import TodoParser
|
||||
from main import process_diff
|
||||
|
||||
|
||||
class IssueUrlInsertionTest(unittest.TestCase):
|
||||
orig_cwd = None
|
||||
tempdir = None
|
||||
diff_file = None
|
||||
parser = None
|
||||
|
||||
def _setUp(self, diff_file):
|
||||
# get current working directory
|
||||
self.orig_cwd = os.getcwd()
|
||||
|
||||
# Create temporary directory to hold simulated filesystem.
|
||||
self.tempdir = tempfile.TemporaryDirectory()
|
||||
|
||||
# run patch against the diff file to generate the simulated filesystem
|
||||
subprocess.run(['patch', '-d', self.tempdir.name,
|
||||
'-i', f'{os.getcwd()}/tests/{diff_file}'],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
check=True)
|
||||
|
||||
self.diff_file = open(f'tests/{diff_file}', 'r')
|
||||
self.parser = TodoParser()
|
||||
with open('syntax.json', 'r') as syntax_json:
|
||||
self.parser.syntax_dict = json.load(syntax_json)
|
||||
|
||||
# change to the simulated filesystem directory
|
||||
os.chdir(self.tempdir.name)
|
||||
|
||||
def _standardTest(self, expected_count):
|
||||
# create object to hold output
|
||||
output = io.StringIO()
|
||||
# process the diffs
|
||||
self.raw_issues = process_diff(diff=self.diff_file, insert_issue_urls=True, parser=self.parser, output=output)
|
||||
# make sure the number of issue URL comments inserted is as expected
|
||||
self.assertEqual(output.getvalue().count('Issue URL successfully inserted'),
|
||||
expected_count,
|
||||
msg='\nProcessing log\n--------------\n'+output.getvalue())
|
||||
|
||||
# this test can take a while and, as far as TodoParser is concerned,
|
||||
# redundant with the tests of test_todo_parser, so enable the means
|
||||
# to skip it if desired
|
||||
@unittest.skipIf(os.getenv('SKIP_PROCESS_DIFF_TEST', 'false') == 'true',
|
||||
"Skipping because 'SKIP_PROCESS_DIFF_TEST' is 'true'")
|
||||
def test_url_insertion(self):
|
||||
self._setUp('test_new.diff')
|
||||
self._standardTest(80)
|
||||
|
||||
# There is a known bug related to this issue, so until it's resolved
|
||||
# this is an expected failure.
|
||||
# See #225 and #224
|
||||
@unittest.expectedFailure
|
||||
def test_same_title_in_same_file(self):
|
||||
self._setUp('test_same_title_in_same_file.diff')
|
||||
self._standardTest(5)
|
||||
|
||||
# There is a known bug related to this issue, so until it's resolved
|
||||
# this is an expected failure.
|
||||
# See #229
|
||||
@unittest.expectedFailure
|
||||
def test_comment_suffix_after_source_line(self):
|
||||
self._setUp('test_comment_suffix_after_source_line.diff')
|
||||
self._standardTest(1)
|
||||
# get details about the issue and source file
|
||||
issue = self.raw_issues[0]
|
||||
markers, _ = self.parser._get_file_details(issue.file_name)
|
||||
with open(f'{self.tempdir.name}/{issue.file_name}', 'r') as source_file:
|
||||
lines = source_file.read().splitlines()
|
||||
# regex search the TODO comment and issue URL lines, such that groups are:
|
||||
# 2: everything from start of line up to (but excluding) comment marker
|
||||
# 3: comment marker
|
||||
# 4: anything after comment marker and before identifier
|
||||
# 1: encompasses all of the above
|
||||
source_and_todo_line = re.search(fr'^((.*?)({markers[0]["pattern"]})(.*?))(?i:{issue.identifier}).*?{issue.title}',
|
||||
lines[issue.start_line-1]).groups()
|
||||
issue_url_line = re.search(fr'^((.*?)({markers[0]["pattern"]})(\s*))Issue URL: N/A$',
|
||||
lines[issue.start_line]).groups()
|
||||
# ensure Issue URL is aligned with the TODO above it by verifying
|
||||
# that length of first group is equal for both lines
|
||||
self.assertEqual(len(source_and_todo_line[0]), len(issue_url_line[0]), msg='\n'
|
||||
+ f'Issue URL mis-alignment. {issue.identifier} begins at column '
|
||||
+ f'{len(source_and_todo_line[0])+1} but\nissue URL begins at column '
|
||||
+ f'{len(issue_url_line[0])+1}.\n'
|
||||
+ '-------------------------------------------------------------------\n'
|
||||
+ f'{lines[issue.start_line-1]}\n'
|
||||
+ f'{lines[issue.start_line]}\n')
|
||||
# ensure Issue URL line has only whitespace before the comment marker
|
||||
self.assertRegex(issue_url_line[1], r'^\s*$', msg='\n'
|
||||
+ 'Non-whitespace detected prior to comment marker for issue URL line!\n'
|
||||
+ '-------------------------------------------------------------------\n'
|
||||
+ f'{lines[issue.start_line]}\n')
|
||||
|
||||
def tearDown(self):
|
||||
# return to original working directory to ensure we don't mess up other tests
|
||||
os.chdir(self.orig_cwd)
|
||||
|
||||
# explicitly cleanup to avoid warning being printed about implicit cleanup
|
||||
self.tempdir.cleanup()
|
||||
self.tempdir = None
|
||||
27
tests/test_same_title_in_same_file.diff
Normal file
27
tests/test_same_title_in_same_file.diff
Normal file
@ -0,0 +1,27 @@
|
||||
diff --git a/Counter.sol b/Counter.sol
|
||||
new file mode 100644
|
||||
index 0000000..d340f6a
|
||||
--- /dev/null
|
||||
+++ b/Counter.sol
|
||||
@@ -0,0 +1,21 @@
|
||||
+contract Counter {
|
||||
+ // TODO: Test this
|
||||
+ // Do it
|
||||
+ // labels: urgent
|
||||
+
|
||||
+ /// TODO: Natspec comment
|
||||
+ /// Do it
|
||||
+ /// labels: urgent
|
||||
+
|
||||
+ /*
|
||||
+ TODO: Test this too
|
||||
+ Do it ASAP
|
||||
+ labels: urgent
|
||||
+ */
|
||||
+
|
||||
+ // TODO: Test this
|
||||
+ /**
|
||||
+ * TODO: Test this too
|
||||
+ * labels: urgent
|
||||
+ */
|
||||
+}
|
||||
@ -16,11 +16,16 @@ def count_issues_for_file_type(raw_issues, file_type):
|
||||
class NewIssueTest(unittest.TestCase):
|
||||
# Check for newly added TODOs across the files specified.
|
||||
def setUp(self):
|
||||
diff_file = open('tests/test_new.diff', 'r')
|
||||
parser = TodoParser()
|
||||
self.raw_issues = []
|
||||
with open('syntax.json', 'r') as syntax_json:
|
||||
parser.syntax_dict = json.load(syntax_json)
|
||||
self.raw_issues = parser.parse(diff_file)
|
||||
with open('tests/test_new.diff', 'r') as diff_file:
|
||||
self.raw_issues.extend(parser.parse(diff_file))
|
||||
with open('tests/test_new2.diff', 'r') as diff_file:
|
||||
self.raw_issues.extend(parser.parse(diff_file))
|
||||
with open('tests/test_edit.diff', 'r') as diff_file:
|
||||
self.raw_issues.extend(parser.parse(diff_file))
|
||||
|
||||
def test_python_issues(self):
|
||||
# Includes 4 tests for Starlark.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user