jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/309965 )
Change subject: [IMPR] Let user the choice which section to be copied ......................................................................
[IMPR] Let user the choice which section to be copied
This patch enables to select all wanted sections step by step or in two bulks for the section types related to the framework and related to the scripts.
A help option is provided to get more information about a section or a section type.
generate_user_files.py: - New SCRIPT_SECTION to differentiate between script and framework settings - Let user the choice which which sections to include. copy_sections() now calls input_sections to get the wanted sections - input_sections() asks which section to be included. Framework sections and scripts section could be included or excluded in bulk or each section step by step. Help options are provided to show the section of the given section type and a short help message for each section to be processed. input_sections also add the selected section to a list; this mutable is hold by copy_sections. - Default response for bulk inclusion is [n]one, default answer of section selection is [n]o. - default parameters of input_sections and copy_sections are for tests purposes only - tests suite doesn't copy the whole sections of user-config.py any longer but uses the SMALL_CONFIG part with its modifications by the batch script. The force parameter is used by the test suite.
generate_user_files_tests.py - tests modified and added
Bug: T145372 Change-Id: I68a04e9198dc179f06c6245f1c1aec518603bd34 --- M tests/generate_user_files_tests.py M pywikibot/scripts/generate_user_files.py 2 files changed, 134 insertions(+), 21 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/scripts/generate_user_files.py b/pywikibot/scripts/generate_user_files.py index 6d4018e..5cfaa09 100755 --- a/pywikibot/scripts/generate_user_files.py +++ b/pywikibot/scripts/generate_user_files.py @@ -2,7 +2,9 @@ """Script to create user-config.py. Other file names are not supported.
.. versionchanged:: 7.0 - moved to pywikibot.scripts folder + moved to pywikibot.scripts folder. +.. versionchanged:: 8.0 + let user the choice which section to be copied. """ # # (C) Pywikibot team, 2010-2022 @@ -18,7 +20,7 @@ from textwrap import fill from typing import Optional
-from pywikibot.backports import Tuple +from pywikibot.backports import Callable, List, Tuple from pywikibot.scripts import _import_with_no_user_config
@@ -33,6 +35,12 @@ OBSOLETE_SECTIONS = { 'ACCOUNT SETTINGS', # already set } +SCRIPT_SECTIONS = { + 'INTERWIKI SETTINGS', + 'SOLVE_DISAMBIGUATION SETTINGS', + 'WEBLINK CHECKER SETTINGS', + 'REPLICATION BOT SETTINGS', +}
# Disable user-config usage as we are creating it here pywikibot = _import_with_no_user_config('pywikibot') @@ -221,6 +229,9 @@ {botpasswords}"""
+ConfigSection = namedtuple('ConfigSection', 'head, info, section') + + def parse_sections() -> list: """Parse sections from config.py file.
@@ -230,7 +241,6 @@ :return: a list of ConfigSection named tuples. """ data = [] - ConfigSection = namedtuple('ConfigSection', 'head, info, section')
config_path = Path(__file__).resolve().parents[1].joinpath('config.py') with codecs.open(config_path, 'r', 'utf-8') as config_f: @@ -250,19 +260,84 @@ return data
-def copy_sections() -> str: +def copy_sections(force: bool = False, default: str = 'n') -> str: """Take config sections and copy them to user-config.py.
+ .. versionchanged:: 8.0 + *force* and *default* options were added. + + :param force: Copy all sections if force is True + :param default: Default answer for input_sections. + Should be 'a' for all or 'n' for none to copy. :return: config text of all selected sections. """ - result = [] sections = parse_sections() - # copy settings - for section in filter(lambda x: x.head not in (DISABLED_SECTIONS - | OBSOLETE_SECTIONS), - sections): - result.append(section.section) - return ''.join(result) + if not sections: # Something is wrong with the regex + return None + + # copy framework settings + copies = input_sections( + 'framework', sections, force=force, default=default, + skip=lambda x: x.head not in (DISABLED_SECTIONS + | OBSOLETE_SECTIONS + | SCRIPT_SECTIONS)) + + # copy scripts settings + copies += input_sections( + 'scripts', sections, force=force, default=default, + skip=lambda x: x.head in SCRIPT_SECTIONS) + + return ''.join(copies) + + +def input_sections(variant: str, + sections: List['ConfigSection'], + skip: Optional[Callable] = None, + force: bool = False, + default: str = 'n') -> None: + """Ask for settings to copy. + + .. versionadded:: 8.0 + + :param variant: Variant of the setting section. Either 'framework' + or 'scripts' + :param sections: A sections list previously read from the config file + :param skip: a filter function + :param force: Force input if True + """ + # First ask what to do which the whole section type variant + select = 'h' + answers = [('Yes', 'y'), ('All', 'a'), ('None', 'n'), ('Help', 'h')] + while select == 'h': + select = pywikibot.input_choice( + f'Do you want to select {variant} setting sections?', + answers, default=default, force=force, automatic_quit=False) + if select == 'h': + answers.pop(-1) + pywikibot.info( + f'The following {variant} setting sections are provided:') + for item in filter(skip, sections): + pywikibot.output(item.head) + + copies = [] + # Now ask for a single section of the given variant + # or use all or none of them + choice = {'a': 'all', 'n': 'none', 'y': 'h'}[select] # mapping + for item in filter(skip, sections): + answers = [('Yes', 'y'), ('No', 'n'), ('Help', 'h')] + while choice == 'h': + choice = pywikibot.input_choice( + f'Do you want to add {item.head} section?', + answers, default='n', force=force, automatic_quit=False) + if choice == 'h': + answers.pop(-1) + pywikibot.info(fill(item.info)) + if choice in ('all', 'y'): + copies.append(item.section) # Fill the mutable directly + if choice not in ('all', 'none'): + choice = 'h' + + return copies
def create_user_config( @@ -331,7 +406,7 @@ "('{}', BotPassword('{}', {!r}))".format(*botpassword) for botpassword in botpasswords)
- config_text = copy_sections() + config_text = copy_sections(force=force) if config_text: config_content = EXTENDED_CONFIG else: diff --git a/tests/generate_user_files_tests.py b/tests/generate_user_files_tests.py index f5e20bd..770ace4 100755 --- a/tests/generate_user_files_tests.py +++ b/tests/generate_user_files_tests.py @@ -84,25 +84,24 @@
def test_copy_sections_not_found(self): """Test copy_sections function for sections not in config text.""" - config_text = guf.copy_sections() + config_text = guf.copy_sections(force=True, default='a') for section in guf.DISABLED_SECTIONS | guf.OBSOLETE_SECTIONS: self.assertNotIn(section, config_text)
def test_copy_sections_found(self): """Test copy_sections function for sections found in config text.""" - config_text = guf.copy_sections() + config_text = guf.copy_sections(force=True, default='a') self.assertIsNotNone(config_text) - for section in ('LOGFILE SETTINGS', - 'EXTERNAL SCRIPT PATH SETTINGS', - 'INTERWIKI SETTINGS', - 'FURTHER SETTINGS', - 'HTTP SETTINGS', - 'REPLICATION BOT SETTINGS', - ): + for section in guf.SCRIPT_SECTIONS: self.assertIn(section, config_text) lines = config_text.splitlines() self.assertGreater(len(lines), 200)
+ def test_copy_sections_none(self): + """Test read_sections function.""" + config_text = guf.copy_sections(force=True) + self.assertEqual(config_text, '') +
if __name__ == '__main__': # pragma: no cover with suppress(SystemExit):
pywikibot-commits@lists.wikimedia.org