1# Copyright (C) 2018 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Tool functions to deal with files."""
15
16import datetime
17import os
18from pathlib import Path
19import textwrap
20
21# pylint: disable=import-error
22from google.protobuf import text_format  # type: ignore
23
24# pylint: disable=import-error
25import metadata_pb2  # type: ignore
26
27ANDROID_TOP = Path(os.environ.get('ANDROID_BUILD_TOP', os.getcwd()))
28EXTERNAL_PATH = ANDROID_TOP / 'external'
29
30METADATA_FILENAME = 'METADATA'
31
32
33def get_absolute_project_path(proj_path: Path) -> Path:
34    """Gets absolute path of a project.
35
36    Path resolution starts from external/.
37    """
38    return EXTERNAL_PATH / proj_path
39
40
41def get_metadata_path(proj_path: Path) -> Path:
42    """Gets the absolute path of METADATA for a project."""
43    return get_absolute_project_path(proj_path) / METADATA_FILENAME
44
45
46def get_relative_project_path(proj_path: Path) -> Path:
47    """Gets the relative path of a project starting from external/."""
48    return get_absolute_project_path(proj_path).relative_to(EXTERNAL_PATH)
49
50
51def read_metadata(proj_path: Path) -> metadata_pb2.MetaData:
52    """Reads and parses METADATA file for a project.
53
54    Args:
55      proj_path: Path to the project.
56
57    Returns:
58      Parsed MetaData proto.
59
60    Raises:
61      text_format.ParseError: Occurred when the METADATA file is invalid.
62      FileNotFoundError: Occurred when METADATA file is not found.
63    """
64
65    with get_metadata_path(proj_path).open('r') as metadata_file:
66        metadata = metadata_file.read()
67        return text_format.Parse(metadata, metadata_pb2.MetaData())
68
69
70def write_metadata(proj_path: Path, metadata: metadata_pb2.MetaData, keep_date: bool) -> None:
71    """Writes updated METADATA file for a project.
72
73    This function updates last_upgrade_date in metadata and write to the project
74    directory.
75
76    Args:
77      proj_path: Path to the project.
78      metadata: The MetaData proto to write.
79      keep_date: Do not change date.
80    """
81
82    if not keep_date:
83        date = metadata.third_party.last_upgrade_date
84        now = datetime.datetime.now()
85        date.year = now.year
86        date.month = now.month
87        date.day = now.day
88    text_metadata = text_format.MessageToString(metadata)
89    with get_metadata_path(proj_path).open('w') as metadata_file:
90        if metadata.third_party.license_type == metadata_pb2.LicenseType.BY_EXCEPTION_ONLY:
91           metadata_file.write(textwrap.dedent("""\
92            # *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS.  PLEASE
93            #     CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
94            #     DEPENDING ON IT IN YOUR PROJECT. ***
95            """))
96        metadata_file.write(text_metadata)
97