File indexing completed on 2024-12-01 05:10:56

0001 """
0002 Module providing search capabilities
0003 """
0004 
0005 # SPDX-FileCopyrightText: 2020 Jonah Brüchert <jbb@kaidan.im>
0006 #
0007 # SPDX-License-Identifier: GPL-2.0-or-later
0008 
0009 import argparse
0010 from typing import Optional
0011 
0012 from lab.allinstancesconnection import AllInstancesConnection
0013 from lab.table import Table
0014 from lab.utils import TextFormatting
0015 
0016 # See: https://docs.gitlab.com/ce/api/projects.html#list-all-projects
0017 SUPPORTED_ORDER_BY_KWS = (
0018     "id",
0019     "name",
0020     "path",
0021     "created_at",
0022     "updated_at",
0023     "last_activity_at",
0024     # Note: Keywords below only work for admins
0025     "repository_size",
0026     "storage_size",
0027     "packages_size",
0028     "wiki_size",
0029 )
0030 
0031 
0032 def parser(
0033     subparsers: argparse._SubParsersAction,  # pylint: disable=protected-access
0034 ) -> argparse.ArgumentParser:
0035     """
0036     Subparser for search command
0037     :param subparsers: subparsers object from global parser
0038     :return: search subparser
0039     """
0040     search_parser: argparse.ArgumentParser = subparsers.add_parser(
0041         "search", help="Search for a repository"
0042     )
0043     search_parser.add_argument(
0044         "search_query",
0045         type=str,
0046         nargs="?",
0047         help="Search query",
0048     )
0049 
0050     search_parser.add_argument(
0051         "--order_by",
0052         dest="order_by",
0053         type=str,
0054         required=False,
0055         choices=SUPPORTED_ORDER_BY_KWS,
0056         help=f"Return projects ordered by {''.join(SUPPORTED_ORDER_BY_KWS)}",
0057     )
0058 
0059     search_parser.add_argument(
0060         "--sort_by",
0061         dest="sort_by",
0062         type=str,
0063         default="desc",
0064         choices=("asc", "desc"),
0065         help="Return projects sorted in asc or desc order. Default is desc.",
0066     )
0067 
0068     return search_parser
0069 
0070 
0071 def run(args: argparse.Namespace) -> None:
0072     """
0073     :param args: parsed arguments
0074     """
0075     search = Search()
0076     search_query = args.search_query[0] if args.search_query else None
0077     search.search_projects(search_query, args.order_by, args.sort_by)
0078 
0079 
0080 class Search(AllInstancesConnection):
0081     """
0082     Search class
0083     """
0084 
0085     def __init__(self) -> None:
0086         AllInstancesConnection.__init__(self)
0087 
0088     def search_projects(
0089         self,
0090         query: Optional[str] = None,
0091         order_by: Optional[str] = None,
0092         sort_by: Optional[str] = None,
0093     ) -> None:
0094         """
0095         Search for a project
0096         :param query: Search query
0097         :param order_by: Order objects by
0098         :param sort_by: sort in asc or desc order
0099         """
0100         table = Table()
0101 
0102         kwargs = {
0103             "search": query,
0104             "order_by": order_by,
0105             "sort_by": sort_by,
0106         }
0107 
0108         for connection in self._connections:
0109             # There are two possible search endpoints: `/search` and `/projects`
0110             # The general search endpoint `/search` only supports `order_by=created_at`
0111             # See: https://docs.gitlab.com/ee/api/search.html#advanced-search-api
0112             for result in connection.projects.list(**kwargs):
0113                 description: Optional[str] = result.description
0114                 if description:
0115                     description = description.replace("\n", "")
0116                     if len(description) > 50:
0117                         description = description[:50] + "…"
0118                 else:
0119                     description = "No description"
0120 
0121                 table.add_row(
0122                     [
0123                         TextFormatting.BOLD + result.path_with_namespace + TextFormatting.END,
0124                         description,
0125                         TextFormatting.UNDERLINE + result.ssh_url_to_repo + TextFormatting.END,
0126                     ]
0127                 )
0128 
0129         table.print()