From c7b8f25fe64412cd06eee16be658ddd3650aa202 Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Tue, 26 Nov 2024 15:28:02 +0100 Subject: [PATCH 1/2] Speed loading commands up --- osc/commandline_common.py | 67 +++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/osc/commandline_common.py b/osc/commandline_common.py index d2247fde..6b1ae93a 100644 --- a/osc/commandline_common.py +++ b/osc/commandline_common.py @@ -1,4 +1,5 @@ import argparse +import copy import importlib import inspect import os @@ -14,6 +15,21 @@ from . import cmdln IN_VENV = getattr(sys, "real_prefix", sys.base_prefix) != sys.prefix +class OscArgumentParser(argparse.ArgumentParser): + def _get_formatter(self): + # cache formatter to speed things a little bit up + if not hasattr(self, "_formatter"): + self._formatter = self.formatter_class(prog=self.prog) + return self._formatter + + def add_argument(self, *args, **kwargs): + # remember added arguments so we can add them to subcommands easily + if not hasattr(self, "_added_arguments"): + self._added_arguments = [] + self._added_arguments.append((args, kwargs)) + super().add_argument(*args, **kwargs) + + class Command: #: Name of the command as used in the argument parser. name: str = None @@ -51,21 +67,27 @@ class Command: ) self.parser.set_defaults(_selected_command=self) else: - self.parser = argparse.ArgumentParser( + self.parser = OscArgumentParser( description=self.get_description(), formatter_class=cmdln.HelpFormatter, usage="%(prog)s [global opts] [--help] [opts] [args]", ) - # traverse the parent commands and add their options to the current command - commands = [] - cmd = self - while cmd: - commands.append(cmd) - cmd = cmd.parent - # iterating backwards to give the command's options a priority over parent/global options - for cmd in reversed(commands): - cmd.init_arguments() + if self.parent: + for arg_args, arg_kwargs in self.parent.parser._added_arguments: + if not arg_args: + continue + if not arg_args[0].startswith("-"): + continue + if "--help" in arg_args: + continue + + arg_kwargs = arg_kwargs.copy() + arg_kwargs["help"] = argparse.SUPPRESS + arg_kwargs["default"] = argparse.SUPPRESS + self.parser.add_argument(*arg_args, **arg_kwargs) + + self.init_arguments() def __repr__(self): return f"" @@ -127,30 +149,7 @@ class Command: Add a new argument to the command's argument parser. See `argparse `_ documentation for allowed parameters. """ - cmd = self - - # Let's inspect if the caller was init_arguments() method. - # In such case use the "parser" argument if specified. - frame_1 = inspect.currentframe().f_back - frame_1_info = inspect.getframeinfo(frame_1) - frame_2 = frame_1.f_back - frame_2_info = inspect.getframeinfo(frame_2) - if (frame_1_info.function, frame_2_info.function) == ("init_arguments", "__init__"): - # this method was called from init_arguments() that was called from __init__ - # let's extract the command class from the 2nd frame and ad arguments there - cmd = frame_2.f_locals["self"] - - # suppress global options from command help - if cmd != self and not self.parent: - kwargs["help"] = argparse.SUPPRESS - - # We're adding hidden options from parent commands to their subcommands to allow - # option intermixing. For all such added hidden options we need to suppress their - # defaults because they would override any option set in the parent command. - if cmd != self: - kwargs["default"] = argparse.SUPPRESS - - cmd.parser.add_argument(*args, **kwargs) + self.parser.add_argument(*args, **kwargs) def init_arguments(self): """ From 7ed288b838dffae546358f10d7db097af218113e Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Tue, 26 Nov 2024 15:31:00 +0100 Subject: [PATCH 2/2] Load most of the modules in commandline.py on-demand --- osc/commandline.py | 819 +++++++++++++++++++++++++++++++++++- osc/commands/repo_add.py | 5 +- osc/commands/repo_list.py | 5 +- osc/commands/repo_remove.py | 5 +- 4 files changed, 813 insertions(+), 21 deletions(-) diff --git a/osc/commandline.py b/osc/commandline.py index 50955aed..53ff6f99 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -12,6 +12,7 @@ import inspect import os import pkgutil import re +import shutil import subprocess import sys import textwrap @@ -26,23 +27,9 @@ from typing import List from urllib.parse import urlsplit from urllib.error import HTTPError -from . import _private -from . import build as osc_build -from . import cmdln from . import commands as osc_commands -from . import conf -from . import git_scm from . import oscerr -from . import output -from . import store as osc_store from .commandline_common import * -from .core import * -from .grabber import OscFileGrabber -from .meter import create_text_meter -from .output import get_user_input -from .output import pipe_to_pager -from .util import cpio, rpmquery, safewriter -from .util.helper import _html_escape, format_table class OscCommand(Command): @@ -144,6 +131,10 @@ class OscMainCommand(MainCommand): ) def post_parse_args(self, args): + from . import conf + from . import store as osc_store + from .meter import create_text_meter + if args.command == "help": # HACK: never ask for credentials when displaying help return @@ -426,6 +417,8 @@ def pop_project_package_from_args( :returns: Project and package. :rtype: tuple(str) """ + from . import store as osc_store + project, package = pop_args( args, arg1_name="project", @@ -709,6 +702,8 @@ class Osc(cmdln.Cmdln): name = 'osc' def __init__(self): + from .util import safewriter + self.options = None self._load_plugins() sys.stderr = safewriter.SafeWriter(sys.stderr) @@ -720,9 +715,16 @@ class Osc(cmdln.Cmdln): print(*args, file=sys.stderr) def get_version(self): + from .core import get_osc_version + return get_osc_version() def _process_project_name(self, project): + from . import conf + from .core import is_package_dir + from .core import is_project_dir + from .core import store_read_project + if isinstance(project, str): if project == '.': if is_package_dir(Path.cwd()) or is_project_dir(Path.cwd()): @@ -803,6 +805,9 @@ class Osc(cmdln.Cmdln): _add_parser_arguments_from_data(parser, arguments) def post_argparse(self): + from . import conf + from .meter import create_text_meter + """merge commandline options into the config""" # handle conflicting options manually because the mutually exclusive group is buggy @@ -850,6 +855,11 @@ class Osc(cmdln.Cmdln): self.download_progress = create_text_meter() def get_api_url(self): + from . import conf + from . import store as osc_store + from .core import is_package_dir + from .core import is_project_dir + try: localdir = Path.cwd() except Exception as e: @@ -867,6 +877,8 @@ class Osc(cmdln.Cmdln): return conf.config['apiurl'] def do_version(self, subcmd, opts): + from .core import get_osc_version + """ Give version of osc binary @@ -880,6 +892,13 @@ class Osc(cmdln.Cmdln): @cmdln.option('package', nargs='?') @cmdln.option('scm_url', nargs='?') def do_init(self, subcmd, opts): + from . import conf + from .core import Package + from .core import Project + from .core import show_files_meta + from .core import show_scmsync + from .core import store_write_string + """ Initialize a directory as working copy @@ -952,6 +971,23 @@ class Osc(cmdln.Cmdln): @cmdln.option('-R', '--revision', metavar='REVISION', help='specify revision (only for sources)') def do_list(self, subcmd, opts, *args): + from .core import ET + from .core import Linkinfo + from .core import Repo + from .core import get_binarylist + from .core import get_repos_of_project + from .core import is_package_dir + from .core import is_project_dir + from .core import meta_get_filelist + from .core import meta_get_packagelist + from .core import meta_get_project_list + from .core import revision_is_empty + from .core import shorttime + from .core import show_files_meta + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ List sources or binaries on the server @@ -1146,6 +1182,8 @@ class Osc(cmdln.Cmdln): @cmdln.option('--extend-package-names', default=False, action="store_true", help='Extend packages names with project name as suffix') def do_addcontainers(self, subcmd, opts, *args): + from . import _private + """ Add maintained containers for a give package @@ -1172,6 +1210,8 @@ class Osc(cmdln.Cmdln): @cmdln.option('-e', '--enable-all', action='store_true', help='Enable all added channels including the ones disabled by default.') def do_addchannels(self, subcmd, opts, *args): + from . import _private + """ Add channels to project @@ -1200,6 +1240,8 @@ class Osc(cmdln.Cmdln): @cmdln.alias('enablechannel') def do_enablechannels(self, subcmd, opts, *args): + from . import _private + """ Enables channels @@ -1222,6 +1264,19 @@ class Osc(cmdln.Cmdln): @cmdln.option('-f', '--force', action='store_true', help='force generation of new patchinfo file, do not update existing one.') def do_patchinfo(self, subcmd, opts, *args): + from .core import Package + from .core import checkout_package + from .core import http_POST + from .core import is_package_dir + from .core import is_project_dir + from .core import makeurl + from .core import meta_get_filelist + from .core import meta_get_packagelist + from .core import run_editor + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Generate and edit a patchinfo file @@ -1299,6 +1354,8 @@ class Osc(cmdln.Cmdln): @cmdln.alias('bsdevelproject') @cmdln.alias('dp') def do_develproject(self, subcmd, opts, *args): + from .core import show_devel_project + """ Print the devel project / package of a package @@ -1320,6 +1377,8 @@ class Osc(cmdln.Cmdln): @cmdln.alias('ca') def do_cleanassets(self, subcmd, opts, *args): + from .core import clean_assets + """ Clean all previous downloaded assets @@ -1329,6 +1388,8 @@ class Osc(cmdln.Cmdln): @cmdln.alias('da') def do_downloadassets(self, subcmd, opts, *args): + from .core import download_assets + """ Download all assets referenced in the build descriptions """ @@ -1338,6 +1399,8 @@ class Osc(cmdln.Cmdln): @cmdln.option('-u', '--unset', action='store_true', help='remove devel project') def do_setdevelproject(self, subcmd, opts, *args): + from .core import set_devel_project + """Set the devel project / package of a package Examples: @@ -1378,6 +1441,8 @@ class Osc(cmdln.Cmdln): set_devel_project(apiurl, project, package, devel_project, devel_package, print_to="stdout") def do_showlinked(self, subcmd, opts, *args): + from . import _private + """ Show all packages linking to a given one @@ -1417,6 +1482,9 @@ class Osc(cmdln.Cmdln): @cmdln.option('--set-release', metavar='RELEASE_TAG', help='Rename binaries during release using this release tag') def do_token(self, subcmd, opts, *args): + from . import conf + from .core import slash_split + """ Show and manage authentication token @@ -1524,6 +1592,28 @@ class Osc(cmdln.Cmdln): @cmdln.option('--delete', action='store_true', help='delete a pattern or attribute') def do_meta(self, subcmd, opts, *args): + from . import _private + from . import conf + from . import store as osc_store + from .core import decode_it + from .core import edit_meta + from .core import get_group_meta + from .core import get_user_meta + from .core import http_DELETE + from .core import http_POST + from .core import makeurl + from .core import metatypes + from .core import show_attribute_meta + from .core import show_package_meta + from .core import show_pattern_meta + from .core import show_pattern_metalist + from .core import show_project_conf + from .core import show_project_meta + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + from .core import streamfile + """ Show meta information, or edit it @@ -1895,6 +1985,31 @@ class Osc(cmdln.Cmdln): @cmdln.alias("submitreq") @cmdln.alias("submitpac") def do_submitrequest(self, subcmd, opts, *args): + from . import _private + from . import conf + from .core import ET + from .core import Package + from .core import _html_escape + from .core import change_request_state + from .core import check_existing_maintenance_requests + from .core import check_existing_requests + from .core import create_submit_request + from .core import decode_it + from .core import edit_message + from .core import highlight_diff + from .core import http_GET + from .core import http_POST + from .core import is_project_dir + from .core import makeurl + from .core import meta_get_packagelist + from .core import parse_diff_for_commit_message + from .core import raw_input + from .core import run_pager + from .core import server_diff + from .core import show_devel_project + from .core import slash_split + from .core import store_read_project + """ Create request to submit source into another Project @@ -2211,6 +2326,20 @@ Please submit there instead, or use --nodevelproject to force direct submission. opts.message or '', result) def _submit_request(self, args, opts, options_block): + from . import conf + from .core import ET + from .core import Package + from .core import get_request_collection + from .core import http_GET + from .core import is_project_dir + from .core import makeurl + from .core import meta_get_packagelist + from .core import raw_input + from .core import server_diff + from .core import show_devel_project + from .core import show_upstream_rev + from .core import store_read_project + actionxml = "" apiurl = self.get_api_url() if len(args) == 0 and is_project_dir(Path.cwd()): @@ -2359,6 +2488,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. return actionxml def _changedevel_request(self, args, opts): + from .core import find_default_project + from .core import is_package_dir + from .core import store_read_package + from .core import store_read_project + if len(args) > 4: raise oscerr.WrongArgs('Too many arguments.') @@ -2403,6 +2537,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. return actionxml def _add_me(self, args, opts): + from . import conf + from .core import get_user_meta + if len(args) > 3: raise oscerr.WrongArgs('Too many arguments.') if len(args) < 2: @@ -2427,6 +2564,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. return actionxml def _add_user(self, args, opts): + from .core import get_user_meta + if len(args) > 4: raise oscerr.WrongArgs('Too many arguments.') if len(args) < 3: @@ -2451,6 +2590,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. return actionxml def _add_group(self, args, opts): + from .core import get_group_meta + if len(args) > 4: raise oscerr.WrongArgs('Too many arguments.') if len(args) < 3: @@ -2475,6 +2616,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. return actionxml def _set_bugowner(self, args, opts): + from .core import get_group_meta + from .core import get_user_meta + if len(args) > 3: raise oscerr.WrongArgs('Too many arguments.') if len(args) < 2: @@ -2523,6 +2667,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='proceed without asking.') @cmdln.alias("creq") def do_createrequest(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import _html_escape + from .core import change_request_state + from .core import edit_message + from .core import http_POST + from .core import makeurl + from .core import slash_split + """ Create a request with multiple actions @@ -2615,6 +2768,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias("reqms") @cmdln.alias("reqbs") def do_requestmaintainership(self, subcmd, opts, *args): + from . import conf + from .core import Request + from .core import edit_message + from .core import is_package_dir + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Requests to add user as maintainer or bugowner @@ -2700,6 +2861,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias("droprequest") @cmdln.alias("deletereq") def do_deleterequest(self, subcmd, opts, *args): + from .core import Request + from .core import edit_message + from .core import is_package_dir + from .core import is_project_dir + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Request to delete (or 'drop') a package or project @@ -2758,6 +2927,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias("cr") @cmdln.alias("changedevelreq") def do_changedevelrequest(self, subcmd, opts, *args): + from .core import Request + from .core import edit_message + from .core import find_default_project + from .core import is_package_dir + from .core import store_read_package + from .core import store_read_project + """ Create request to change the devel package definition @@ -2857,6 +3033,39 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias("review") # FIXME: rewrite this mess and split request and review def do_request(self, subcmd, opts, *args): + from . import _private + from . import conf + from .core import ET + from .core import change_request_state + from .core import change_request_state_template + from .core import change_review_state + from .core import check_existing_requests + from .core import checkout_package + from .core import clone_request + from .core import create_submit_request + from .core import edit_message + from .core import get_request + from .core import get_request_collection + from .core import get_request_log + from .core import get_results + from .core import get_review_list + from .core import get_user_projpkgs_request_list + from .core import highlight_diff + from .core import http_GET + from .core import http_POST + from .core import makeurl + from .core import print_comments + from .core import raw_input + from .core import request_diff + from .core import request_interactive_review + from .core import run_pager + from .core import show_package_meta + from .core import show_project_meta + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + from .core import submit_action_diff + """ Show or modify requests and reviews @@ -3384,6 +3593,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--vrev', metavar='vrev', help='Enforce a given vrev') def do_setlinkrev(self, subcmd, opts, *args): + from .core import Package + from .core import meta_get_packagelist + from .core import parseRevisionOption + from .core import set_link_rev + """ Updates a revision number in a source link @@ -3438,6 +3652,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(f"Set link revision of package {project}/{p} to {rev}") def do_linktobranch(self, subcmd, opts, *args): + from .core import Package + from .core import link_to_branch + """ Convert a package containing a classic link with patch to a branch @@ -3468,6 +3685,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify message TEXT') def do_detachbranch(self, subcmd, opts, *args): + from .core import ET + from .core import Linkinfo + from .core import copy_pac + from .core import delete_files + from .core import show_files_meta + from .core import show_package_meta + """ Replace a link with its expanded sources @@ -3521,6 +3745,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-N', '--new-package', action='store_true', help='create a link to a not yet existing package') def do_linkpac(self, subcmd, opts, *args): + from .core import link_pac + from .core import parseRevisionOption + from .core import show_upstream_rev_vrev + """ "Link" a package to another package @@ -3586,6 +3814,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-d', '--disable-publish', action='store_true', help='disable publishing of the aggregated package') def do_aggregatepac(self, subcmd, opts, *args): + from .core import aggregate_pac + """ "Aggregate" a package to another package @@ -3640,6 +3870,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-e', '--expand', action='store_true', help='if the source package is a link then copy the expanded version of the link') def do_copypac(self, subcmd, opts, *args): + from . import conf + from .core import copy_pac + from .core import decode_it + from .core import parseRevisionOption + from .core import show_upstream_rev + """ Copy a package @@ -3718,6 +3954,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--no-delay', action='store_true', help="Don't put the release job in a queue to be run later, but immediately run it. Thus the next call to osc prjresult will reflect it. Otherwise there is no way to know if it is finished or didn't start yet.") def do_release(self, subcmd, opts, *args): + from . import _private + """ Release sources and binaries @@ -3752,6 +3990,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-p', '--package', metavar='PKG', action='append', help='specify packages to release') def do_releaserequest(self, subcmd, opts, *args): + from .core import ET + from .core import Request + from .core import create_release_request + from .core import edit_message + from .core import is_project_dir + from .core import show_project_meta + from .core import slash_split + from .core import store_read_project + """ Create a release request @@ -3818,6 +4065,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify message TEXT') def do_createincident(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import http_POST + from .core import makeurl + from .core import search + from .core import slash_split + """ Create a maintenance incident @@ -3891,6 +4145,20 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Superseding another request by this one') @cmdln.alias("mr") def do_maintenancerequest(self, subcmd, opts, *args): + from . import _private + from . import conf + from .core import Package + from .core import change_request_state + from .core import check_existing_maintenance_requests + from .core import create_maintenance_request + from .core import edit_message + from .core import is_package_dir + from .core import is_project_dir + from .core import search + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Create a request for starting a maintenance incident @@ -4019,6 +4287,16 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('sm') @cmdln.alias('maintained') def do_mbranch(self, subcmd, opts, *args): + from . import conf + from .core import Project + from .core import attribute_branch_pkg + from .core import checkout_package + from .core import get_source_rev + from .core import meta_get_packagelist + from .core import output + from .core import slash_split + from .core import statfrmt + """ Search or branch multiple instances of a package @@ -4138,6 +4416,19 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--disable-build', action='store_true', help='disable building of the branched package') def do_branch(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import branch_pkg + from .core import checkout_package + from .core import find_default_project + from .core import is_package_dir + from .core import output + from .core import print_request_list + from .core import show_attribute_meta + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Branch a package @@ -4268,6 +4559,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify log message TEXT') def do_undelete(self, subcmd, opts, *args): + from .core import edit_message + from .core import undelete_package + from .core import undelete_project + """ Restores a deleted project or package on the server @@ -4300,6 +4595,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify log message TEXT') def do_rdelete(self, subcmd, opts, *args): + from .core import delete_package + from .core import delete_project + from .core import edit_message + """ Delete a project or packages on the server @@ -4336,6 +4635,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify log message TEXT') def do_lock(self, subcmd, opts, *args): + from .core import lock + """ Locks a project or package @@ -4356,6 +4657,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-m', '--message', metavar='TEXT', help='specify log message TEXT') def do_unlock(self, subcmd, opts, *args): + from .core import edit_message + from .core import unlock_package + from .core import unlock_project + """ Unlocks a project or package @@ -4384,6 +4689,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('', '--specfile', metavar='FILE', help='Path to specfile. (if you pass more than working copy this option is ignored)') def do_updatepacmetafromspec(self, subcmd, opts, *args): + from .core import Package + from .core import parseargs + """ Update package meta information from a specfile @@ -4422,6 +4730,17 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-u', '--unexpand', action='store_true', help='Local changes only, ignore changes in linked package sources') def do_diff(self, subcmd, opts, *args): + from .core import ET + from .core import Package + from .core import highlight_diff + from .core import http_GET + from .core import makeurl + from .core import parseRevisionOption + from .core import parseargs + from .core import run_pager + from .core import server_diff + from .core import server_diff_noex + """ Generates a diff @@ -4539,6 +4858,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--xml', action='store_true', help='show diff as xml (only for issues diff)') def do_rdiff(self, subcmd, opts, *args): + from .core import decode_it + from .core import highlight_diff + from .core import parseRevisionOption + from .core import run_pager + from .core import server_diff_noex + """ Server-side "pretty" diff of two packages @@ -4612,6 +4937,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. raise oscerr.PackageMissing(project, package, msg or f'{project}/{package} does not exist.') def _pdiff_package_exists(self, apiurl, project, package): + from .core import show_package_meta + try: show_package_meta(apiurl, project, package) return True @@ -4638,6 +4965,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. return (None, None) def _pdiff_get_parent_from_link(self, apiurl, project, package): + from .core import ET + from .core import http_GET + from .core import makeurl + link_url = makeurl(apiurl, ['source', project, package, '_link']) try: @@ -4658,6 +4989,10 @@ Please submit there instead, or use --nodevelproject to force direct submission. return (parent_project, parent_package) def _pdiff_get_exists_and_parent(self, apiurl, project, package): + from .core import ET + from .core import http_GET + from .core import makeurl + link_url = makeurl(apiurl, ['source', project, package]) try: file = http_GET(link_url) @@ -4689,6 +5024,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. dest='nomissingok', help='fail if the parent package does not exist on the server') def do_pdiff(self, subcmd, opts, *args): + from .core import highlight_diff + from .core import is_package_dir + from .core import is_project_dir + from .core import run_pager + from .core import server_diff + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Quick alias to diff the content of a package with its parent @@ -4772,6 +5116,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. return False def _prdiff_output_diff(self, opts, rdiff): + from .core import decode_it + if opts.diffstat: print() with subprocess.Popen("diffstat", stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True) as p: @@ -4824,6 +5170,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-d', '--diffstat', action='store_true', help='show diffstat of differences') def do_prdiff(self, subcmd, opts, *args): + from .core import Project + from .core import get_request_collection + from .core import is_project_dir + from .core import meta_get_packagelist + from .core import server_diff_noex + """ Server-side diff of two projects @@ -4907,6 +5259,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(f"new only: {pkg}") def do_repourls(self, subcmd, opts, *args): + from . import _private + from .core import decode_it + from .core import get_buildconfig + from .core import get_repositories_of_project + from .core import return_external + from .core import store_read_project + """ Shows URLs of .repo files @@ -4954,6 +5313,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(url_tmpl % (project.replace(':', ':/'), repo, project)) def do_browse(self, subcmd, opts, *args): + from . import _private + from .core import run_external + """ Opens browser @@ -5011,6 +5373,29 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Do not clone native scm repositories: Different representation and you will not be able to submit changes!') @cmdln.alias('co') def do_checkout(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import Linkinfo + from .core import Project + from .core import checkRevision + from .core import checkout_deleted_package + from .core import checkout_package + from .core import get_osc_version + from .core import get_source_file + from .core import is_project_dir + from .core import meta_get_packagelist + from .core import parseRevisionOption + from .core import print_request_list + from .core import revision_is_empty + from .core import run_external + from .core import show_files_meta + from .core import show_project_meta + from .core import show_scmsync + from .core import show_upstream_srcmd5 + from .core import slash_split + from .core import statfrmt + from .core import store_read_project + """ Check out content from the repository @@ -5179,6 +5564,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. '"exclude_glob" config option') @cmdln.alias('st') def do_status(self, subcmd, opts, *args): + from .core import Package + from .core import Project + from .core import compare + from .core import is_project_dir + from .core import parseargs + from .core import statfrmt + """ Show status of files in working copy @@ -5244,6 +5636,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-f', '--force', action='store_true', help='add files even if they are excluded by the exclude_glob config option') def do_add(self, subcmd, opts, *args): + from .core import addDownloadUrlService + from .core import addFiles + from .core import addGitSource + from .core import parseargs + """ Mark files to be added upon the next commit @@ -5273,6 +5670,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. def do_mkpac(self, subcmd, opts, *args): + from . import conf + from .core import createPackageDir + """ Create a new package under version control @@ -5294,6 +5694,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='If CWD is a project dir then scan all package dirs as well') @cmdln.alias('ar') def do_addremove(self, subcmd, opts, *args): + from . import conf + from .core import Package + from .core import Project + from .core import addFiles + from .core import getTransActPath + from .core import is_project_dir + from .core import parseargs + from .core import statfrmt + """ Adds new files, removes disappeared files @@ -5362,6 +5771,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option("--skip-local-service-run", "--noservice", "--no-service", default=False, action="store_true", help="Skip run of local source services as specified in _service file.") def do_commit(self, subcmd, opts, *args): + from .core import get_default_editor + """ Upload content to the repository server @@ -5389,6 +5800,16 @@ Please submit there instead, or use --nodevelproject to force direct submission. return 1 def _commit(self, subcmd, opts, args): + from . import conf + from .core import Package + from .core import Project + from .core import edit_message + from .core import get_commit_msg + from .core import is_project_dir + from .core import parseargs + from .core import raw_input + from .core import store_unlink_file + args = parseargs(args) msg = '' @@ -5531,6 +5952,19 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Skip all files with a given size') @cmdln.alias('up') def do_update(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import Linkinfo + from .core import Package + from .core import Project + from .core import checkRevision + from .core import is_project_dir + from .core import parseRevisionOption + from .core import parseargs + from .core import print_request_list + from .core import show_files_meta + from .core import show_upstream_rev + """ Update a working copy @@ -5661,6 +6095,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('del') @cmdln.alias('remove') def do_delete(self, subcmd, opts, *args): + from . import conf + from .core import Package + from .core import Project + from .core import getPrjPacPaths + from .core import getTransActPath + from .core import is_project_dir + from .core import parseargs + from .core import statfrmt + """ Mark files or package directories to be deleted upon the next 'checkin' @@ -5727,6 +6170,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. sys.exit(f'\'{filename}\' is marked as skipped and no local file with this name exists') def do_resolved(self, subcmd, opts, *args): + from .core import Package + from .core import parseargs + """ Remove 'conflicted' state on working copy files @@ -5758,6 +6204,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('dists') def do_distributions(self, subcmd, opts, *args): + from .core import get_distributions + from .util.helper import format_table + """ Shows all available distributions @@ -5783,6 +6232,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('package') @cmdln.option('files', metavar="file", nargs='+') def do_rremove(self, subcmd, opts): + from .core import delete_files + from .core import raw_input + """ Remove source files from selected package """ @@ -5852,6 +6304,19 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--show-excluded', action='store_true', help='show repos that are excluded for this package') def do_results(self, subcmd, opts, *args): + from .core import MultibuildFlavorResolver + from .core import csv + from .core import decode_it + from .core import get_package_results + from .core import get_results + from .core import io + from .core import is_package_dir + from .core import is_project_dir + from .core import result_xml_to_dicts + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Shows the build results of a package or project @@ -5982,6 +6447,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='show packages that are excluded in all repos, also hide repos that have only excluded packages') @cmdln.alias('pr') def do_prjresults(self, subcmd, opts, *args): + from .core import decode_it + from .core import get_package_results + from .core import get_prj_results + from .core import store_read_project + """ Shows project-wide build results @@ -6024,6 +6494,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('rpmlint') @cmdln.alias('lint') def do_rpmlintlog(self, subcmd, opts, *args): + from . import build as osc_build + from .core import decode_it + from .core import get_rpmlint_log + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Shows the rpmlint logfile @@ -6073,6 +6550,16 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-s', '--strip-time', action='store_true', help='strip leading build time from the log') def do_buildlog(self, subcmd, opts, *args): + from . import build as osc_build + from . import conf + from .core import ET + from .core import http_GET + from .core import makeurl + from .core import parse_buildlogurl + from .core import print_buildlog + from .core import store_read_package + from .core import store_read_project + """ Shows the build log of a package @@ -6139,6 +6626,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. print_buildlog(apiurl, project, package, repository, arch, offset, strip_time, opts.last, opts.lastsucceeded) def print_repos(self, repos_only=False, exc_class=oscerr.WrongArgs, exc_msg='Missing arguments', project=None): + from .core import is_package_dir + from .core import is_project_dir + wd = Path.cwd() doprint = False if is_package_dir(wd): @@ -6179,6 +6669,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-s', '--strip-time', action='store_true', help='strip leading build time from the log') def do_remotebuildlog(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import http_GET + from .core import makeurl + from .core import parse_buildlogurl + from .core import print_buildlog + from .core import slash_split + """ Shows the build log of a package @@ -6233,6 +6731,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. print_buildlog(apiurl, project, package, repository, arch, offset, strip_time, opts.last, opts.lastsucceeded) def _find_last_repo_arch(self, repo=None, fatal=True): + from .core import ET + from .core import store + files = glob.glob(os.path.join(Path.cwd(), store, "_buildinfo-*")) if repo is not None: files = [f for f in files @@ -6257,6 +6758,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-s', '--strip-time', action='store_true', help='strip leading build time from the log') def do_localbuildlog(self, subcmd, opts, *args): + from . import build as osc_build + from . import conf + from .core import BUFSIZE + from .core import buildlog_strip_time + from .core import is_package_dir + from .core import store_read_package + from .core import store_read_project + """ Shows the build log of a local buildchroot @@ -6310,6 +6819,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-M', '--multibuild-package', metavar='FLAVOR', help=HELP_MULTIBUILD_ONE) @cmdln.alias('tr') def do_triggerreason(self, subcmd, opts, *args): + from .core import ET + from .core import is_package_dir + from .core import show_package_trigger_reason + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Show reason why a package got triggered to build @@ -6424,6 +6940,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. self._dependson(True, opts, *args) def _dependson(self, reverse, opts, *args): + from .core import ET + from .core import get_dependson + from .core import is_package_dir + from .core import is_project_dir + from .core import meta_get_packagelist + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + wd = Path.cwd() args = slash_split(args) project = packages = repository = arch = None @@ -6482,6 +7007,16 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--nodebugpackages', '--no-debug-packages', action='store_true', help='Skip installation of additional debug packages for CLI builds (specified in obs:cli_debug_packages in project metadata)') def do_buildinfo(self, subcmd, opts, *args): + from . import build as osc_build + from .core import decode_it + from .core import get_buildconfig + from .core import get_buildinfo + from .core import is_package_dir + from .core import return_external + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Shows the build info @@ -6586,6 +7121,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(decode_it(buildinfo)) def do_buildconfig(self, subcmd, opts, *args): + from .core import decode_it + from .core import get_buildconfig + from .core import is_package_dir + from .core import is_project_dir + from .core import slash_split + from .core import store_read_project + """ Shows the build config @@ -6629,6 +7171,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('worker', metavar=':') def do_workerinfo(self, subcmd, opts): + from .core import get_worker_info + """ Gets the information to a worker from the server @@ -6647,6 +7191,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-M', '--multibuild-package', metavar='FLAVOR', help=HELP_MULTIBUILD_ONE) def do_checkconstraints(self, subcmd, opts, *args): + from .core import check_constraints + from .core import get_repos_of_project + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Check the constraints and view compliant workers @@ -6722,6 +7272,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('repos') @cmdln.alias('platforms') def do_repositories(self, subcmd, opts, *args): + from .core import build_table + from .core import get_repos_of_project + from .core import get_repositories_of_project + from .core import is_package_dir + from .core import is_project_dir + from .core import show_package_disabled_repos + from .core import store_read_package + from .core import store_read_project + """ Shows repositories configured for a project @@ -6775,6 +7334,19 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(row) def parse_repoarchdescr(self, args, noinit=False, alternative_project=None, ignore_descr=False, vm_type=None, multibuild_package=None): + from . import build as osc_build + from . import conf + from .core import Package + from .core import Repo + from .core import decode_it + from .core import get_buildconfig + from .core import get_repos_of_project + from .core import is_package_dir + from .core import return_external + from .core import store + from .core import store_read_package + from .core import store_read_project + """helper to parse the repo, arch and build description from args""" arg_arch = arg_repository = arg_descr = None if len(args) < 3: @@ -7074,6 +7646,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('shell') @cmdln.alias('wipe') def do_build(self, subcmd, opts, *args): + from . import build as osc_build + from . import conf + from . import git_scm + from . import store as osc_store + from .core import Project + from .output import get_user_input + """ Build a package on your local machine @@ -7139,7 +7718,7 @@ Please submit there instead, or use --nodevelproject to force direct submission. # OSC_BUILD_ROOT overrides the setting of build-root. # OSC_PACKAGECACHEDIR overrides the setting of packagecachedir. """ - if which(conf.config['build-cmd']) is None: + if shutil.which(conf.config['build-cmd']) is None: print(f"Error: build ('{conf.config['build-cmd']}') command not found", file=sys.stderr) print('Install the build package from http://download.opensuse.org/repositories/openSUSE:/Tools/', file=sys.stderr) return 1 @@ -7284,6 +7863,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. return self._do_rbuild(subcmd, opts, *args) def _do_rbuild(self, subcmd, opts, *args): + from .core import run_external + # drop the --argument, value tuple from the list def drop_arg2(lst, name): @@ -7424,6 +8005,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. help=HELP_MULTIBUILD_ONE) @cmdln.alias('buildhist') def do_buildhistory(self, subcmd, opts, *args): + from . import _private + """ Shows the build history of a package @@ -7465,6 +8048,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. help=HELP_MULTIBUILD_ONE) @cmdln.alias('jobhist') def do_jobhistory(self, subcmd, opts, *args): + from .core import is_package_dir + from .core import is_project_dir + from .core import print_jobhistory + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Shows the job history of a project @@ -7527,6 +8117,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-M', '--meta', action='store_true', default=None, help='checkout out meta data instead of sources') def do_log(self, subcmd, opts, *args): + from .core import checkRevision + from .core import get_commitlog + from .core import parseRevisionOption + from .core import revision_is_empty + from .output import pipe_to_pager + """ Shows the commit log of a package @@ -7558,6 +8154,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-v', '--verbose', action='store_true', help='verbose run of local services for debugging purposes') def do_service(self, subcmd, opts, *args): + from . import store as osc_store + from .core import Package + from .core import mergeservice + from .core import runservice + from .core import waitservice + """ Handle source services @@ -7661,6 +8263,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Rebuild all packages of entire project') @cmdln.alias('rebuildpac') def do_rebuild(self, subcmd, opts, *args): + from .core import MultibuildFlavorResolver + from .core import rebuild + """ Trigger package rebuilds @@ -7714,6 +8319,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(rebuild(apiurl, project, package, repo, arch, code)) def do_info(self, subcmd, opts, *args): + from . import store as osc_store + from .core import Package + from .core import Project + from .core import parseargs + """ Print information about a working copy @@ -7733,6 +8343,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-M', '--multibuild-package', metavar='FLAVOR', action='append', help=HELP_MULTIBUILD_MANY) def do_sendsysrq(self, subcmd, opts, *args): + from . import store as osc_store + from .core import MultibuildFlavorResolver + from .core import cmdbuild + from .core import is_package_dir + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Trigger a sysrq in a running build @@ -7787,6 +8405,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Restart all running builds of entire project') @cmdln.alias('abortbuild') def do_restartbuild(self, subcmd, opts, *args): + from . import store as osc_store + from .core import MultibuildFlavorResolver + from .core import cmdbuild + from .core import is_package_dir + from .core import is_project_dir + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Restart the build of a certain project or package @@ -7854,6 +8481,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Delete all binaries regardless of the package status (previously default)') @cmdln.alias("unpublish") def do_wipebinaries(self, subcmd, opts, *args): + from .core import MultibuildFlavorResolver + from .core import is_package_dir + from .core import is_project_dir + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + from .core import unpublish + from .core import wipebinaries + """ Delete all binary packages of a certain project/package @@ -7934,6 +8570,18 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--ccache', action="store_true", help='allow fetching ccache archive') def do_getbinaries(self, subcmd, opts, *args): + from .core import MultibuildFlavorResolver + from .core import get_binary_file + from .core import get_binarylist + from .core import get_repos_of_project + from .core import is_package_dir + from .core import is_project_dir + from .core import meta_get_packagelist + from .core import output + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Download binaries to a local directory @@ -8080,6 +8728,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--maintained', action='store_true', help='limit search results to packages with maintained attribute set.') def do_my(self, subcmd, opts, *args): + from . import conf + from .core import ET + from .core import Request + from .core import get_request_collection + from .core import get_user_projpkgs + from .core import get_user_projpkgs_request_list + from .core import http_GET + from .core import makeurl + """ Show waiting work, packages, projects or requests involving yourself @@ -8331,6 +8988,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('se') @cmdln.alias('bse') def do_search(self, subcmd, opts, *args): + from . import conf + from .core import build_table + from .core import filter_role + from .core import get_source_rev + from .core import search + from .core import xpath_join + """ Search for a project and/or package @@ -8563,6 +9227,22 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='commit the new files') @cmdln.option('srpm') def do_importsrcpkg(self, subcmd, opts): + from . import conf + from . import store as osc_store + from .core import ET + from .core import Package + from .core import Project + from .core import addFiles + from .core import createPackageDir + from .core import edit_meta + from .core import is_project_dir + from .core import meta_exists + from .core import parse_meta_to_string + from .core import store_read_project + from .core import unpack_srcrpm + from .grabber import OscFileGrabber + from .util import rpmquery + """ Import a new package from a src.rpm @@ -8701,6 +9381,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('url', help="either URL '/path' or full URL with 'scheme://hostname/path'") def do_api(self, subcmd, opts): + from .core import edit_text + from .core import http_request + """ Issue an arbitrary request to the API @@ -8785,6 +9468,26 @@ Please submit there instead, or use --nodevelproject to force direct submission. help='Define message as commit entry or request description') @cmdln.alias('bugowner') def do_maintainer(self, subcmd, opts, *args): + from .core import ET + from .core import _html_escape + from .core import addPerson + from .core import build_table + from .core import delPerson + from .core import edit_message + from .core import get_group_data + from .core import get_user_data + from .core import http_POST + from .core import makeurl + from .core import owner + from .core import raw_input + from .core import setBugowner + from .core import set_devel_project + from .core import show_package_meta + from .core import show_project_meta + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + """ Show maintainers according to server side configuration @@ -9068,6 +9771,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('user') @cmdln.option('user', nargs='*') def do_whois(self, subcmd, opts): + from . import conf + """ Show fullname and email of a buildservice user """ @@ -9097,6 +9802,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option("repository") @cmdln.option("arch") def do_create_pbuild_config(self, subcmd, opts): + from .core import create_pbuild_config + from .core import is_package_dir + from .core import is_project_dir + from .core import store_read_project + """ This command is creating the necessary files to build using pbuild tool. It basically creates _config and _pbuild file in the project directory. @@ -9134,6 +9844,17 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.alias('blame') @cmdln.alias('less') def do_cat(self, subcmd, opts, *args): + from .core import http_GET + from .core import is_package_dir + from .core import makeurl + from .core import parseRevisionOption + from .core import run_pager + from .core import show_upstream_srcmd5 + from .core import slash_split + from .core import store_read_package + from .core import store_read_project + from .core import streamfile + """ Output the content of a file to standard output @@ -9201,6 +9922,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. # helper function to download a file from a specific revision def download(self, name, md5, dir, destfile): + from .core import BUFSIZE + from .core import http_GET + from .core import makeurl + from .core import streamfile + o = open(destfile, 'wb') if md5 != '': query = {'rev': dir['srcmd5']} @@ -9212,6 +9938,19 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-d', '--destdir', default='repairlink', metavar='DIR', help='destination directory') def do_repairlink(self, subcmd, opts, *args): + from .core import ET + from .core import Package + from .core import binary_file + from .core import http_GET + from .core import is_package_dir + from .core import makeurl + from .core import run_external + from .core import slash_split + from .core import statfrmt + from .core import store_read_package + from .core import store_read_project + from .core import store_write_string + """ Repair a broken source link @@ -9407,6 +10146,15 @@ Please submit there instead, or use --nodevelproject to force direct submission. print('run \'osc resolved ...\', and commit the changes.') def do_pull(self, subcmd, opts, *args): + from .core import ET + from .core import Package + from .core import binary_file + from .core import http_GET + from .core import makeurl + from .core import run_external + from .core import statfrmt + from .core import store_write_string + """ Merge the changes of the link target into your working copy """ @@ -9546,6 +10294,13 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--sslcert', action='store_true', default=False, help='fetch SSL certificate instead of GPG key') def do_signkey(self, subcmd, opts, *args): + from .core import http_DELETE + from .core import http_POST + from .core import is_package_dir + from .core import is_project_dir + from .core import makeurl + from .core import store_read_project + """ Manage Project Signing Key @@ -9635,6 +10390,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-e', '--just-edit', action='store_true', default=False, help='just open changes (cannot be used with -m)') def do_vc(self, subcmd, opts, *args): + from . import conf + from . import store as osc_store + from .core import is_package_dir + from .core import vc_export_env + from .core import which + """ Edit the changes file @@ -9722,6 +10483,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('source') @cmdln.option('dest') def do_mv(self, subcmd, opts): + from .core import Package + """ Move SOURCE file to DEST and keep it under version control """ @@ -9770,6 +10533,9 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--dump-full', action='store_true', help='dump the complete configuration (including \'pass\' and \'passx\' options)') def do_config(self, subcmd, opts, *args): + from . import conf + from .core import raw_input + """ Get/set a config option @@ -9853,6 +10619,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('file', nargs='+') def do_revert(self, subcmd, opts): + from .core import Package + """ Restore changed files or the entire working copy @@ -9872,6 +10640,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('--force-apiurl', action='store_true', help='ask once for an apiurl and force this apiurl for all inconsistent projects/packages') def do_repairwc(self, subcmd, opts, *args): + from . import conf + from .core import Package + from .core import Project + from .core import is_package_dir + from .core import is_project_dir + from .core import parseargs + from .core import raw_input + """ Try to repair an inconsistent working copy @@ -9944,6 +10720,11 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-n', '--dry-run', action='store_true', help='print the results without actually removing a file') def do_clean(self, subcmd, opts, *args): + from .core import Package + from .core import getTransActPath + from .core import is_package_dir + from .core import parseargs + """ Removes all untracked files from the package working copy @@ -9978,6 +10759,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. @cmdln.option('-p', '--parent', help='reply to comment with parent id', metavar='PARENT') def do_comment(self, subcmd, opts, *args): + from .core import create_comment + from .core import delete_comment + from .core import edit_text + from .core import print_comments + from .core import slash_split + """ List / create / delete comments @@ -10044,6 +10831,8 @@ Please submit there instead, or use --nodevelproject to force direct submission. print(result) def _load_plugins(self): + from . import output + if IN_VENV: output.print_msg("Running in virtual environment, skipping loading legacy plugins.", print_to="debug") return diff --git a/osc/commands/repo_add.py b/osc/commands/repo_add.py index 9c8dadb9..b6597b82 100644 --- a/osc/commands/repo_add.py +++ b/osc/commands/repo_add.py @@ -1,9 +1,7 @@ import difflib import osc.commandline -from .. import obs_api from .. import oscerr -from ..output import get_user_input class RepoAddCommand(osc.commandline.OscCommand): @@ -54,6 +52,9 @@ class RepoAddCommand(osc.commandline.OscCommand): ) def run(self, args): + from .. import obs_api + from ..output import get_user_input + paths = [] for path in args.paths: if "/" not in path: diff --git a/osc/commands/repo_list.py b/osc/commands/repo_list.py index 111a7e21..5ecdfec9 100644 --- a/osc/commands/repo_list.py +++ b/osc/commands/repo_list.py @@ -1,6 +1,4 @@ import osc.commandline -from .. import obs_api -from ..output import KeyValueTable class RepoListCommand(osc.commandline.OscCommand): @@ -19,6 +17,9 @@ class RepoListCommand(osc.commandline.OscCommand): ) def run(self, args): + from .. import obs_api + from ..output import KeyValueTable + project_obj = obs_api.Project.from_api(args.apiurl, args.project) repo_flags = project_obj.resolve_repository_flags() diff --git a/osc/commands/repo_remove.py b/osc/commands/repo_remove.py index 5832a438..648d96f0 100644 --- a/osc/commands/repo_remove.py +++ b/osc/commands/repo_remove.py @@ -1,9 +1,7 @@ import difflib import osc.commandline -from .. import obs_api from .. import oscerr -from ..output import get_user_input class RepoRemoveCommand(osc.commandline.OscCommand): @@ -34,6 +32,9 @@ class RepoRemoveCommand(osc.commandline.OscCommand): ) def run(self, args): + from .. import obs_api + from ..output import get_user_input + project_obj = obs_api.Project.from_api(args.apiurl, args.project) old = project_obj.to_string()