"""This script compares a local feature file to that in Jira"""
import argparse
import difflib
import getpass
import os
import pathlib
import sys
import tempfile
from pytest_bdd import feature
from pytest_bdd.exceptions import FeatureError
from ska_ser_skallop.scripts.bdd_helper_scripts.xtp_utils import (
XrayException,
export_xtp_feature,
get_xtp_issue_type,
)
[docs]def download_xtp_feature(args, xtp_ticket, delete_file=True):
json_response = export_xtp_feature(args, xtp_ticket)
parsed_feature_file = None
with tempfile.NamedTemporaryFile("w+b", delete=delete_file) as tmp_file:
tmp_file.write(json_response.content)
tmp_file.seek(0)
try:
parsed_feature_file = feature.get_feature("", tmp_file.name)
except FeatureError as err:
print(f"\nThere is a problem with the feature file from {xtp_ticket}:\n")
print(err)
sys.exit(1)
return parsed_feature_file
[docs]def get_file_paths(directory: str) -> list[str]:
"""Return the valid `*.feature` file paths.
:param directory: Path to the location of a directory of `*.feature` files
:return: A list of pathlib.PosixPath objects.
"""
file_paths = []
for file_path in pathlib.Path(directory).iterdir():
if file_path.is_file():
if file_path.name.startswith("XTP-") and file_path.name.endswith(
".feature"
):
file_paths.append(file_path)
return file_paths
[docs]def file_differences(args: argparse.Namespace, file_paths: list[str]) -> bool:
"""Compares and format output as the unix "diff" command. Writes the output to
stdout.
:param args: The parsed parameters
:param file_paths: A list of pathlib.Posix objects
:return: Whether or not there was a difference
"""
is_different = False
for file_path in file_paths:
xtp_ticket_number = file_path.name.split(".")[0]
remote_feature_file = download_xtp_feature(
args, xtp_ticket_number, delete_file=False
)
if args.verbose:
issue_type = get_xtp_issue_type(args, xtp_ticket_number)
print(
f"Downloaded {xtp_ticket_number} [Type: {issue_type}]",
file=sys.stderr,
)
with open(remote_feature_file.filename) as remote_file, open(
file_path
) as local_file:
remote_file_content = remote_file.readlines()
local_file_content = local_file.readlines()
if args.verbose:
print(
f"Comparing local {file_path} file against remote "
f"{xtp_ticket_number}.feature file."
)
delta = difflib.unified_diff(local_file_content, remote_file_content)
# Need a way to tell if there were any differences identified between the files.
# So checking if the generator can be yielded. Then set a flag to indicate to
# the script to exit with an error.
try:
next(delta)
except StopIteration:
print(
f"Local {file_path} file and remote {xtp_ticket_number}.feature file "
"are the same."
)
else:
is_different = True
sys.stdout.writelines(
difflib.unified_diff(
local_file_content,
remote_file_content,
fromfile=f"{xtp_ticket_number}-local.feature",
tofile=f"{xtp_ticket_number}-remote.feature",
)
)
return is_different
[docs]def check_local_file():
"""
Check the local feature file - Empty method
:return: the list of issues; an empty list.
"""
issues = []
return issues
[docs]def parse_local_feature_files():
"""
Empty method
:return: list of local features; an empty list.
"""
local_features = []
return local_features
[docs]def main():
"""Script entrypoint"""
parser = argparse.ArgumentParser(prog="xtp-compare")
file_dir_group = parser.add_mutually_exclusive_group(required=True)
file_dir_group.add_argument(
"-d",
"--directory",
required=False,
default="",
help="Path to the location of a directory of '*.feature' files",
)
file_dir_group.add_argument(
"-f",
"--feature-file",
required=False,
default="",
help="Path to the location of a 'XTP-*.feature' file",
)
parser.add_argument(
"-u", "--username", type=str, default="", help="JIRA account username"
)
parser.add_argument(
"-p",
"--password",
type=str,
default="",
help=(
"When authenticating with a username, you will be prompted for a password "
"if you don't use this option"
),
)
parser.add_argument(
"-v",
"--verbose",
required=False,
action="store_true",
help="Verbose output",
)
args = parser.parse_args()
setattr(args, "jira_auth_token", os.environ.get("JIRA_AUTH", None))
if not args.jira_auth_token:
if not args.username:
print(
"A username is required when the environment variable JIRA_AUTH is not "
"set"
)
sys.exit(0)
if not args.password:
stdin_password = getpass.getpass()
setattr(args, "password", stdin_password)
# Make sure the directory and file is valid
file_paths = []
if args.directory:
if not os.path.isdir(args.directory):
print(f"{args.directory} is not a directory")
sys.exit(1)
file_paths = get_file_paths(args.directory)
if args.feature_file:
if not os.path.isfile(args.feature_file):
print(f"{args.feature_file} is not a file")
sys.exit(1)
file_paths = [pathlib.Path(args.feature_file)]
try:
if file_differences(args, file_paths):
sys.exit(1)
except XrayException as err:
raise SystemExit(err) from err
if __name__ == "__main__":
main()