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 d2247fde0..6b1ae93a6 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 @@ 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 @@ def __init__(self, full_name, parent=None): ) 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 @@ def add_argument(self, *args, **kwargs): 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 50955aedc..53ff6f995 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -12,6 +12,7 @@ import os import pkgutil import re +import shutil import subprocess import sys import textwrap @@ -26,23 +27,9 @@ 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 @@ def init_arguments(self): ) 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 @@ def _debug(self, *args): 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 @@ def _add_parser_arguments_from_data(argument_parser, data): _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 @@ def post_argparse(self): 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 @@ def get_api_url(self): 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 @@ def do_version(self, subcmd, opts): @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 @@ def do_init(self, subcmd, opts): @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 @@ def do_list(self, subcmd, opts, *args): @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 @@ def do_addcontainers(self, subcmd, opts, *args): @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 @@ def do_addchannels(self, subcmd, opts, *args): @cmdln.alias('enablechannel') def do_enablechannels(self, subcmd, opts, *args): + from . import _private + """ Enables channels @@ -1222,6 +1264,19 @@ def do_enablechannels(self, subcmd, opts, *args): @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 @@ def do_patchinfo(self, subcmd, opts, *args): @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 @@ def do_develproject(self, subcmd, opts, *args): @cmdln.alias('ca') def do_cleanassets(self, subcmd, opts, *args): + from .core import clean_assets + """ Clean all previous downloaded assets @@ -1329,6 +1388,8 @@ def do_cleanassets(self, subcmd, opts, *args): @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 @@ def do_downloadassets(self, subcmd, opts, *args): @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 @@ def do_setdevelproject(self, subcmd, opts, *args): 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 @@ def do_showlinked(self, subcmd, opts, *args): @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 @@ def do_token(self, subcmd, opts, *args): @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 @@ def do_meta(self, subcmd, opts, *args): @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 @@ def _check_service(root): 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 @@ def _delete_request(self, args, opts): 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 @@ def _release_request(self, args, opts): 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 @@ def _add_me(self, args, opts): 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 @@ def _add_user(self, args, opts): 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 @@ def _add_group(self, args, opts): 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 @@ def _set_bugowner(self, args, opts): 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 @@ def do_createrequest(self, subcmd, opts, *args): @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 @@ def do_requestmaintainership(self, subcmd, opts, *args): @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 @@ def do_deleterequest(self, subcmd, opts, *args): @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 @@ def do_changedevelrequest(self, subcmd, opts, *args): @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 @@ def do_request(self, subcmd, opts, *args): @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 @@ def do_setlinkrev(self, subcmd, opts, *args): 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 @@ def do_linktobranch(self, subcmd, opts, *args): @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 @@ def do_detachbranch(self, subcmd, opts, *args): @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 @@ def do_linkpac(self, subcmd, opts, *args): @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 @@ def do_aggregatepac(self, subcmd, opts, *args): @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 @@ def do_copypac(self, subcmd, opts, *args): @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 @@ def do_release(self, subcmd, opts, *args): @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 @@ def do_releaserequest(self, subcmd, opts, *args): @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 @@ def do_createincident(self, subcmd, opts, *args): 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 @@ def do_maintenancerequest(self, subcmd, opts, *args): @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 @@ def do_mbranch(self, subcmd, opts, *args): @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 @@ def do_branch(self, subcmd, opts, *args): @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 @@ def do_undelete(self, subcmd, opts, *args): @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 @@ def do_rdelete(self, subcmd, opts, *args): @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 @@ def do_lock(self, subcmd, opts, *args): @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 @@ def do_unlock(self, subcmd, opts, *args): @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 @@ def do_updatepacmetafromspec(self, subcmd, opts, *args): @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 @@ def do_diff(self, subcmd, opts, *args): @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 @@ def _pdiff_raise_non_existing_package(self, project, package, msg=None): 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 @@ def _pdiff_guess_parent(self, apiurl, project, package, check_exists_first=False 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 @@ def _pdiff_get_parent_from_link(self, apiurl, project, package): 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 @@ def _pdiff_get_exists_and_parent(self, apiurl, project, package): 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 @@ def _prdiff_skip_package(self, opts, pkg): 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 @@ def _prdiff_output_matching_requests(self, opts, requests, @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 @@ def do_prdiff(self, subcmd, opts, *args): 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 @@ def _repo_type(apiurl, project, repo): 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 @@ def do_browse(self, subcmd, opts, *args): 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 @@ def do_checkout(self, subcmd, opts, *args): '"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 @@ def do_status(self, subcmd, opts, *args): @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 @@ def do_add(self, subcmd, opts, *args): 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 @@ def do_mkpac(self, subcmd, opts, *args): 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 @@ def do_addremove(self, subcmd, opts, *args): @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 @@ def do_commit(self, subcmd, opts, *args): 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 @@ def _commit(self, subcmd, opts, args): 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 @@ def do_update(self, subcmd, opts, *args): @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 @@ def do_delete(self, subcmd, opts, *args): 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 @@ def do_resolved(self, subcmd, opts, *args): @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 @@ def do_distributions(self, subcmd, opts, *args): @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 @@ def do_rremove(self, subcmd, opts): @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 @@ def do_results(self, subcmd, opts, *args): 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 @@ def do_prjresults(self, subcmd, opts, *args): @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 @@ def do_rpmlintlog(self, subcmd, opts, *args): @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 @@ def do_buildlog(self, subcmd, opts, *args): 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 @@ def print_repos(self, repos_only=False, exc_class=oscerr.WrongArgs, exc_msg='Mis @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 @@ def do_remotebuildlog(self, subcmd, opts, *args): 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 @@ def _find_last_repo_arch(self, repo=None, fatal=True): @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 @@ def do_localbuildlog(self, subcmd, opts, *args): @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 @@ def do_whatdependson(self, subcmd, opts, *args): 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 @@ def _dependson(self, reverse, opts, *args): @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 @@ def do_buildinfo(self, subcmd, opts, *args): 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 @@ def do_buildconfig(self, subcmd, opts, *args): @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 @@ def do_workerinfo(self, subcmd, opts): @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 @@ def do_checkconstraints(self, subcmd, opts, *args): @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 @@ def do_repositories(self, subcmd, opts, *args): 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 @@ def parse_repoarchdescr(self, args, noinit=False, alternative_project=None, igno @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 @@ def do_build(self, subcmd, opts, *args): # 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 @@ def do_build(self, subcmd, opts, *args): 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 @@ def rsync_dirs_2host(hostargs, short_name, long_name, dirs): 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 @@ def do_buildhistory(self, subcmd, opts, *args): 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 @@ def do_jobhistory(self, subcmd, opts, *args): @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 @@ def do_log(self, subcmd, opts, *args): @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 @@ def do_service(self, subcmd, opts, *args): 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 @@ def do_rebuild(self, subcmd, opts, *args): 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 @@ def do_info(self, subcmd, opts, *args): @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 @@ def do_sendsysrq(self, subcmd, opts, *args): 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 @@ def do_restartbuild(self, subcmd, opts, *args): 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 @@ def do_wipebinaries(self, subcmd, opts, *args): @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 @@ def do_getbinaries(self, subcmd, opts, *args): @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 @@ def do_my(self, subcmd, opts, *args): @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 @@ def build_xpath(attr, what, substr=False): 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 @@ def do_importsrcpkg(self, subcmd, opts): @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 @@ def do_api(self, subcmd, opts): 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 @@ def setBugownerHelper(apiurl, project, package, bugowner): @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 @@ def do_whois(self, subcmd, opts): @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 @@ def do_create_pbuild_config(self, subcmd, opts): @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 @@ def do_cat(self, subcmd, opts, *args): # 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 @@ def download(self, name, md5, dir, destfile): @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 @@ def do_repairlink(self, subcmd, opts, *args): 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 @@ def do_pull(self, subcmd, opts, *args): @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 @@ def do_signkey(self, subcmd, opts, *args): @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 @@ def do_vc(self, subcmd, opts, *args): @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 @@ def do_mv(self, subcmd, opts): @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 @@ def do_config(self, subcmd, opts, *args): @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 @@ def do_revert(self, subcmd, opts): @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 @@ def get_apiurl(apiurls): @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 @@ def do_clean(self, subcmd, opts, *args): @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 @@ def do_comment(self, subcmd, opts, *args): 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 9c8dadb9f..b6597b82c 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 @@ def init_arguments(self): ) 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 111a7e21d..5ecdfec96 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 @@ def init_arguments(self): ) 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 5832a438f..648d96f0d 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 @@ def init_arguments(self): ) 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()