aboutsummaryrefslogtreecommitdiffstats
path: root/import_issues.py
diff options
context:
space:
mode:
Diffstat (limited to 'import_issues.py')
-rwxr-xr-ximport_issues.py93
1 files changed, 86 insertions, 7 deletions
diff --git a/import_issues.py b/import_issues.py
index 1c27f80..b7195bf 100755
--- a/import_issues.py
+++ b/import_issues.py
@@ -50,7 +50,13 @@
# and USERS dicts below, if desired, or these features can be disabled. See the
# documentation for these variables.
#
-# 4. The projects I have tested this on are small, and don't make use of many of
+# 4. If your project has confidential issues or comments in it, then you will
+# need to decide to exclude them with --skip-confidential, or include them all
+# with --include-confidential. If there are confidential items and you don't
+# pass either of these options, then an exception will be thrown. If you need
+# more fine-grained control over confidential items, edit issues.ndjson by hand.
+#
+# 5. The projects I have tested this on are small, and don't make use of many of
# Gitlab's features. This may bork on more complex projects.
@@ -210,6 +216,7 @@ def open_ticket(
created_at: str,
closed_at: Optional[str],
is_closed: bool,
+ is_confidential: bool,
label_names: List[str],
milestone_name: Optional[str],
gitlab_ticket_url: str,
@@ -236,6 +243,9 @@ def open_ticket(
if label_names:
pheaders.append("Labels: " + ", ".join(sorted(label_names)))
+ if is_confidential:
+ pheaders.append("Confidential: true")
+
lines.append(" \\\n".join(pheaders))
lines.append("")
lines.append(body)
@@ -307,12 +317,22 @@ def send_comment(
created_at: str,
last_edited_at: str,
is_system: bool,
+ is_confidential: bool,
):
lines = []
+ pheaders = []
+
+ # Pseudo-headers, if any.
+ if is_confidential:
+ pheaders.append("Confidential: true")
+
+ if pheaders:
+ lines.append(" \\\n".join(pheaders))
+ lines.append("")
+ # Authorship note for a regular comment.
if is_system:
- # (Skipping pseudoheaders array here, only have one.)
- lines.append(f"Changed at: {created_at}")
+ lines.append(f"Changed on {created_at} by {author_name}:")
else:
lines.append(f"On {created_at}, {author_name} wrote:")
@@ -378,6 +398,8 @@ def run(
gitlab_project_url: str,
skip_missing_issues: bool,
create_missing_issues: bool,
+ include_confidential: bool,
+ skip_confidential: bool,
):
milestone_jsons = []
with open(export_dir_path / 'milestones.ndjson') as milestones_file:
@@ -393,15 +415,51 @@ def run(
for line in issues_file:
issue_jsons.append(json.loads(line))
+ if skip_confidential:
+ issue_jsons = [x for x in issue_jsons if not x.get('confidential')]
+ for issue_json in issue_jsons:
+ issue_json['notes'] = [
+ n
+ for n in issue_json['notes']
+ if not n.get('confidential')
+ ]
+
+ elif not include_confidential:
+ have_confidential_issues = any(
+ x.get('confidential')
+ for x in issue_jsons
+ )
+ have_confidential_notes = any(
+ n.get('confidential')
+ for x in issue_jsons
+ for n in x['notes']
+ )
+ confidential_types = []
+ if have_confidential_issues:
+ confidential_types.append('issues')
+ if have_confidential_notes:
+ confidential_types.append('notes')
+ assert not (have_confidential_issues or have_confidential_notes), \
+ f"Found confidential {' and '.join(confidential_types)}; please " \
+ f"decide whether these should all be included, then pass either " \
+ f"--include-confidential or --skip-confidential, or edit " \
+ f"issues.ndjson for more fine-grained control."
+
issue_jsons.sort(key=lambda x: x['iid'])
max_issue_id = max(x['iid'] for x in issue_jsons)
present_issue_id_set = {x['iid'] for x in issue_jsons}
missing_issue_ids = set(range(1, max_issue_id + 1)) - present_issue_id_set
if missing_issue_ids and not (skip_missing_issues or create_missing_issues):
+ if skip_confidential:
+ because_confidential_msg = \
+ " (possibly because some confidential issues were excluded)"
+ else:
+ because_confidential_msg = ""
+
raise RuntimeError(
- f"Don't have all issues from 1 to {max_issue_id}, please pass "
- f"--create-missing-issues or --skip-missing-issues to proceed."
+ f"Don't have all issues from 1 to {max_issue_id}{because_confidential_msg}, "
+ f"please pass --create-missing-issues or --skip-missing-issues to proceed."
)
issues_by_id = {}
@@ -463,6 +521,7 @@ def run(
created_at=issue_json['created_at'],
closed_at=issue_json['closed_at'],
is_closed=(issue_json['state'] == 'closed'),
+ is_confidential=(issue_json.get('confidential') is True),
label_names=[x['label']['title'] for x in issue_json['label_links']],
milestone_name=issue_json.get('milestone', {}).get('title') or None,
gitlab_ticket_url=f"{gitlab_project_url}/-/issues/{gitlab_issue_id}",
@@ -519,6 +578,7 @@ def run(
created_at=note_json['created_at'],
last_edited_at=note_json['last_edited_at'],
is_system=note_json['system'],
+ is_confidential=(note_json['confidential'] is True),
)
print("-------- CLOSING CLOSED ISSUES")
@@ -619,6 +679,18 @@ def main():
)
parser.add_argument(
+ '--include-confidential',
+ action='store_true',
+ help="Include confidential tickets and notes.",
+ )
+
+ parser.add_argument(
+ '--skip-confidential',
+ action='store_true',
+ help="Skip confidential tickets and notes.",
+ )
+
+ parser.add_argument(
'export_dir',
help='Exported Gitlab tree/project/ directory containing ndjson files.',
)
@@ -639,6 +711,11 @@ def main():
assert not (skip_missing_issues and create_missing_issues), \
f"Can accept at most one of --skip-missing-issues and --create-missing-issues."
+ include_confidential = args['include_confidential']
+ skip_confidential = args['skip_confidential']
+ assert not (include_confidential and skip_confidential), \
+ f"Can accept at most one of --include-confidential and --skip-confidential."
+
if mode == 'print':
smtp = None
elif mode == 'send':
@@ -672,8 +749,10 @@ def main():
frm=frm,
export_dir_path=export_dir_path,
gitlab_project_url=args['gitlab_project_url'].rstrip('/'),
- skip_missing_issues=args['skip_missing_issues'],
- create_missing_issues=args['create_missing_issues'],
+ skip_missing_issues=skip_missing_issues,
+ create_missing_issues=create_missing_issues,
+ include_confidential=include_confidential,
+ skip_confidential=skip_confidential,
)
if mode == 'send':