1# Copyright 2021 Google LLC
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#     https://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
15from enum import IntEnum
16import numpy as np
17import pandas as pd
18import pathlib
19
20from changesummary import ChangeType
21
22SCRIPTS_DIR = pathlib.Path(__file__).parent.resolve()
23CHANGE_SUMMARY_DIR = SCRIPTS_DIR / "temp"
24
25
26class BuildPrBody:
27    """Represents the PR body which contains the change summary between 2
28    directories containing artifacts.
29    """
30
31    def __init__(self, change_summary_directory):
32        """Initializes an instance of a BuildPrBody.
33
34        Args:
35            change_summary_directory (str): The relative path to the directory
36            which contains the change summary output.
37        """
38        self._change_summary_directory = change_summary_directory
39
40    def get_commit_uri(self, name):
41        """Return a uri to the last commit for the given API Name.
42
43        Args:
44            name (str): The name of the api.
45        """
46
47        url = "https://github.com/googleapis/google-api-python-client/commit/"
48        sha = None
49        api_link = ""
50
51        file_path = pathlib.Path(self._change_summary_directory) / "{0}.sha".format(name)
52        if file_path.is_file():
53            with open(file_path, "r") as f:
54                sha = f.readline().rstrip()
55                if sha:
56                    api_link = "{0}{1}".format(url, sha)
57
58        return api_link
59
60    def generate_pr_body(self):
61        """
62        Generates a PR body given an input file `'allapis.dataframe'` and
63        writes it to disk with file name `'allapis.summary'`.
64        """
65        directory = pathlib.Path(self._change_summary_directory)
66        dataframe = pd.read_csv(directory / "allapis.dataframe")
67        dataframe["Version"] = dataframe["Version"].astype(str)
68
69        dataframe["Commit"] = np.vectorize(self.get_commit_uri)(dataframe["Name"])
70
71        stable_and_breaking = (
72            dataframe[
73                dataframe["IsStable"] & (dataframe["ChangeType"] == ChangeType.DELETED)
74            ][["Name", "Version", "Commit"]]
75            .drop_duplicates()
76            .agg(" ".join, axis=1)
77            .values
78        )
79
80        prestable_and_breaking = (
81            dataframe[
82                (dataframe["IsStable"] == False)
83                & (dataframe["ChangeType"] == ChangeType.DELETED)
84            ][["Name", "Version", "Commit"]]
85            .drop_duplicates()
86            .agg(" ".join, axis=1)
87            .values
88        )
89
90        all_apis = (
91            dataframe[["Summary", "Commit"]]
92            .drop_duplicates()
93            .agg(" ".join, axis=1)
94            .values
95        )
96
97        with open(directory / "allapis.summary", "w") as f:
98            if len(stable_and_breaking) > 0:
99                f.writelines(
100                    [
101                        "## Deleted keys were detected in the following stable discovery artifacts:\n",
102                        "\n".join(stable_and_breaking),
103                        "\n\n",
104                    ]
105                )
106
107            if len(prestable_and_breaking) > 0:
108                f.writelines(
109                    [
110                        "## Deleted keys were detected in the following pre-stable discovery artifacts:\n",
111                        "\n".join(prestable_and_breaking),
112                        "\n\n",
113                    ]
114                )
115
116            if len(all_apis) > 0:
117                f.writelines(
118                    [
119                        "## Discovery Artifact Change Summary:\n",
120                        "\n".join(all_apis),
121                        "\n",
122                    ]
123                )
124
125
126if __name__ == "__main__":
127    BuildPrBody(CHANGE_SUMMARY_DIR).generate_pr_body()
128