# SPDX-FileCopyrightText: 2019 Free Software Foundation Europe e.V. <https://fsfe.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions for REUSE-ifying a project."""
import re
import sys
from argparse import ArgumentParser, Namespace
from gettext import gettext as _
from inspect import cleandoc
from pathlib import Path
from typing import IO, List
from urllib.error import URLError
from ._licenses import ALL_NON_DEPRECATED_MAP
from ._util import (
_LICENSEREF_PATTERN,
PathType,
print_incorrect_spdx_identifier,
)
from .download import _path_to_license_file, put_license_in_file
from .project import Project
from .vcs import find_root
[docs]def prompt_licenses(out: IO[str] = sys.stdout) -> List[str]:
"""Prompt the user for a list of licenses."""
first = _(
"What license is your project under? "
"Provide the SPDX License Identifier. "
"See <https://spdx.org/licenses/> for the list."
)
multi = _(
"What other license is your project under? "
"Provide the SPDX License Identifier."
)
licenses: List[str] = []
while True:
if not licenses:
out.write(first)
else:
out.write(multi)
out.write("\n")
out.write(_("To stop adding licenses, hit RETURN."))
out.write("\n")
result = input()
out.write("\n")
if not result:
return licenses
if result not in ALL_NON_DEPRECATED_MAP and not re.match(
_LICENSEREF_PATTERN, result
):
print_incorrect_spdx_identifier(result, out=out)
out.write("\n\n")
else:
licenses.append(result)
[docs]def add_arguments(parser: ArgumentParser) -> None:
"""Add arguments to parser."""
parser.add_argument(
"path",
action="store",
nargs="?",
type=PathType("r", force_directory=True),
)
[docs]def run(
args: Namespace,
project: Project,
out: IO[str] = sys.stdout,
) -> int:
"""List all non-compliant files."""
# pylint: disable=too-many-statements,unused-argument
if args.path:
root = args.path
else:
root = find_root()
if root is None:
root = Path.cwd()
if (root / ".reuse").exists():
out.write(_("Project already initialized"))
out.write("\n")
return 1
out.write(_("Initializing project for REUSE."))
out.write("\n\n")
licenses = prompt_licenses(out=out)
out.write(_("What is the name of the project?"))
out.write("\n")
project_name = input()
out.write("\n")
out.write(_("What is the internet address of the project?"))
out.write("\n")
project_url = input()
out.write("\n")
out.write(_("What is the name of the maintainer?"))
out.write("\n")
contact_name = input()
out.write("\n")
out.write(_("What is the e-mail address of the maintainer?"))
out.write("\n")
contact_address = input()
out.write("\n")
out.write(_("All done! Initializing now."))
out.write("\n\n")
# Creating files past this point!
for lic in licenses:
destination = _path_to_license_file(lic, root=root)
try:
out.write(_("Retrieving {}").format(lic))
out.write("\n")
put_license_in_file(lic, destination=destination)
# TODO: exceptions
except FileExistsError:
out.write(_("{} already exists").format(destination))
out.write("\n")
except URLError:
out.write(_("Could not download {}").format(lic))
out.write("\n")
except FileNotFoundError as err:
out.write(
_(
"Error: Could not copy {path}, "
"please add {lic}.txt manually in the LICENCES/ directory."
).format(path=err.filename, lic=lic)
)
out.write("\n")
out.write("\n")
out.write(_("Creating .reuse/dep5"))
out.write("\n\n")
# pylint: disable=line-too-long
dep5_text = cleandoc(
f"""
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: {project_name}
Upstream-Contact: {contact_name} <{contact_address}>
Source: {project_url}
# Sample paragraph, commented out:
#
# Files: src/*
# Copyright: $YEAR $NAME <$CONTACT>
# License: ...
"""
)
dep5_text += "\n"
(root / ".reuse").mkdir()
(root / ".reuse/dep5").write_text(dep5_text)
out.write(_("Initialization complete."))
out.write("\n")
return 0