<NME> init.py
<BEF> #!/usr/bin/env python3
#
# init.py - part of the FDroid server tools
# Copyright (C) 2010-2013, Ciaran Gultnieks, ciaran@ciarang.com
# Copyright (C) 2013-2014 Daniel Martí <mvdan@mvdan.cc>
# Copyright (C) 2013 Hans-Christoph Steiner <hans@eds.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import glob
import os
import re
import shutil
import socket
import sys
from argparse import ArgumentParser
import logging

from . import _
from . import common
from .exception import FDroidException

config = {}
options = None


def disable_in_config(key, value):
    """Write a key/value to the local config.yml, then comment it out."""
    import yaml

    with open('config.yml') as f:
        data = f.read()
    pattern = r'\n[\s#]*' + key + r':.*'
    repl = '\n#' + yaml.dump({key: value}, default_flow_style=False)
    data = re.sub(pattern, repl, data)
    with open('config.yml', 'w') as f:
        f.writelines(data)


def main():

    global options, config

    # Parse command line...
    parser = ArgumentParser()
    common.setup_global_opts(parser)
    parser.add_argument(
        "-d",
        "--distinguished-name",
        default=None,
        help=_("X.509 'Distinguished Name' used when generating keys"),
    )
    parser.add_argument(
        "--keystore",
        default=None,
        help=_("Path to the keystore for the repo signing key"),
    )
    parser.add_argument(
        "--repo-keyalias",
        default=None,
        help=_("Alias of the repo signing key in the keystore"),
    )
    parser.add_argument(
        "--android-home",
        default=None,
        help=_("Path to the Android SDK (sometimes set in ANDROID_HOME)"),
    )
    parser.add_argument(
        "--no-prompt",
        action="store_true",
        default=False,
        help=_("Do not prompt for Android SDK path, just fail"),
    )
    options = parser.parse_args()

    fdroiddir = os.getcwd()
    test_config = dict()
    examplesdir = common.get_examples_dir()
    common.fill_config_defaults(test_config)

    # track down where the Android SDK is, the default is to use the path set
    # in ANDROID_HOME if that exists, otherwise None
    if options.android_home is not None:
        test_config['sdk_path'] = options.android_home
    elif not common.test_sdk_exists(test_config):
        # if neither --android-home nor the default sdk_path
        # exist, prompt the user using platform-specific default
        # and if the user leaves it blank, ignore and move on.
        default_sdk_path = ''
        if sys.platform in ('win32', 'cygwin'):
            p = os.path.join(
                os.getenv('USERPROFILE'), 'AppData', 'Local', 'Android', 'android-sdk'
            )
        elif sys.platform == 'darwin':
            # on OSX, Homebrew is common and has an easy path to detect
            p = '/usr/local/opt/android-sdk'
        elif os.path.isdir('/usr/lib/android-sdk'):
            # if the Debian packages are installed, suggest them
            p = '/usr/lib/android-sdk'
        else:
            p = '/opt/android-sdk'
        if os.path.exists(p):
            default_sdk_path = p
            test_config['sdk_path'] = default_sdk_path

        if not common.test_sdk_exists(test_config):
            del (test_config['sdk_path'])
            while not options.no_prompt:
                try:
                    s = input(
                        _('Enter the path to the Android SDK (%s) here:\n> ')
                        % default_sdk_path
                    )
                except KeyboardInterrupt:
                    print('')
                    sys.exit(1)
                if re.match(r'^\s*$', s) is not None:
                    test_config['sdk_path'] = default_sdk_path
                else:
                    test_config['sdk_path'] = s
                if common.test_sdk_exists(test_config):
                    break
                default_sdk_path = ''

    if test_config.get('sdk_path') and not common.test_sdk_exists(test_config):
        raise FDroidException(
            _("Android SDK not found at {path}!").format(path=test_config['sdk_path'])
        )

    if not os.path.exists('config.yml') and not os.path.exists('config.py'):
        # 'metadata' and 'tmp' are created in fdroid
        if not os.path.exists('repo'):
            os.mkdir('repo')
        example_config_yml = os.path.join(examplesdir, 'config.yml')
        if os.path.exists(example_config_yml):
            shutil.copyfile(example_config_yml, 'config.yml')
        else:
            from pkg_resources import get_distribution

            versionstr = get_distribution('fdroidserver').version
            if not versionstr:
                versionstr = 'master'
            with open('config.yml', 'w') as fp:
                fp.write('# see https://gitlab.com/fdroid/fdroidserver/blob/')
                fp.write(versionstr)
                fp.write('/examples/config.yml\n')
        os.chmod('config.yml', 0o0600)
        # If android_home is None, test_config['sdk_path'] will be used and
        # "$ANDROID_HOME" may be used if the env var is set up correctly.
        # If android_home is not None, the path given from the command line
        # will be directly written in the config.
        if 'sdk_path' in test_config:
            common.write_to_config(test_config, 'sdk_path', options.android_home)
    else:
        logging.warning(
            'Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...'
        )
        logging.info('Try running `fdroid init` in an empty directory.')
        raise FDroidException('Repository already exists.')

    # now that we have a local config.yml, read configuration...
    config = common.read_config(options)

    # the NDK is optional and there may be multiple versions of it, so it's
    # left for the user to configure

                             + '" does not exist, creating a new keystore there.')
    common.write_to_config(test_config, 'keystore', keystore)
    repo_keyalias = None
    if options.repo_keyalias:
        repo_keyalias = options.repo_keyalias
        common.write_to_config(test_config, 'repo_keyalias', repo_keyalias)
    if options.keystore:
        keystore = os.path.abspath(options.keystore)
        if options.keystore == 'NONE':
            keystore = options.keystore
        else:
            keystore = os.path.abspath(options.keystore)
            if not os.path.exists(keystore):
                logging.info(
                    '"' + keystore + '" does not exist, creating a new keystore there.'
                )
    common.write_to_config(test_config, 'keystore', keystore)
    repo_keyalias = None
    keydname = None
    if options.repo_keyalias:
        repo_keyalias = options.repo_keyalias
        common.write_to_config(test_config, 'repo_keyalias', repo_keyalias)
    if options.distinguished_name:
        keydname = options.distinguished_name
        common.write_to_config(test_config, 'keydname', keydname)
    if keystore == 'NONE':  # we're using a smartcard
        common.write_to_config(
            test_config, 'repo_keyalias', '1'
        )  # seems to be the default
        disable_in_config('keypass', 'never used with smartcard')
        common.write_to_config(
            test_config,
            'smartcardoptions',
                                   flags=re.MULTILINE)
            with open('opensc-fdroid.cfg', 'w') as f:
                f.write(opensc_fdroid)
    elif not os.path.exists(keystore):
        password = common.genpassword()
        c = dict(test_config)
        c['keystorepass'] = password
                if len(files) > 0:
                    opensc_so = files[0]
                else:
                    opensc_so = '/usr/lib/opensc-pkcs11.so'
                    logging.warning(
                        'No OpenSC PKCS#11 module found, '
                        + 'install OpenSC then edit "opensc-fdroid.cfg"!'
                    )
            with open('opensc-fdroid.cfg', 'w') as f:
                f.write('name = OpenSC\nlibrary = ')
                f.write(opensc_so)
                f.write('\n')
        logging.info(
            "Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.yml."
        )
        logging.info(
            "If you want to generate a new repo signing key in the HSM you can do that with 'fdroid update "
            "--create-key'."
        )
    elif os.path.exists(keystore):
        to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname']
        if repo_keyalias:
            to_set.remove('repo_keyalias')
        if keydname:
            to_set.remove('keydname')
        logging.warning(
            '\n'
            + _('Using existing keystore "{path}"').format(path=keystore)
            + '\n'
            + _('Now set these in config.yml:')
            + ' '
            + ', '.join(to_set)
            + '\n'
        )
    else:
        password = common.genpassword()
        c = dict(test_config)
        c['keystorepass'] = password
        c['keypass'] = password
        c['repo_keyalias'] = socket.getfqdn()
        c['keydname'] = 'CN=' + c['repo_keyalias'] + ', OU=F-Droid'
        common.write_to_config(test_config, 'keystorepass', password)
        common.write_to_config(test_config, 'keypass', password)
        common.write_to_config(test_config, 'repo_keyalias', c['repo_keyalias'])
        common.write_to_config(test_config, 'keydname', c['keydname'])
        common.genkeystore(c)

    msg = '\n'
    msg += _('Built repo based in "%s" with this config:') % fdroiddir
    msg += '\n\n  Android SDK:\t\t\t' + config['sdk_path']
    msg += '\n  ' + _('Keystore for signing key:\t') + keystore
    if repo_keyalias is not None:
        msg += '\n  Alias for key in store:\t' + repo_keyalias
    msg += '\n\n'
    msg += (
        _(
            '''To complete the setup, add your APKs to "%s"
then run "fdroid update -c; fdroid update".  You might also want to edit
"config.yml" to set the URL, repo name, and more.  You should also set up
a signing key (a temporary one might have been automatically generated).

For more info: https://f-droid.org/docs/Setup_an_F-Droid_App_Repo
and https://f-droid.org/docs/Signing_Process'''
        )
        % os.path.join(fdroiddir, 'repo')
    )
    logging.info(msg)

<MSG> init: handle case where keystore.jks is present but config.py is not

<DFF> @@ -178,6 +178,7 @@ def main():
                              + '" does not exist, creating a new keystore there.')
     common.write_to_config(test_config, 'keystore', keystore)
     repo_keyalias = None
+    keydname = None
     if options.repo_keyalias:
         repo_keyalias = options.repo_keyalias
         common.write_to_config(test_config, 'repo_keyalias', repo_keyalias)
@@ -211,7 +212,16 @@ def main():
                                    flags=re.MULTILINE)
             with open('opensc-fdroid.cfg', 'w') as f:
                 f.write(opensc_fdroid)
-    elif not os.path.exists(keystore):
+    elif os.path.exists(keystore):
+        to_set = ['keystorepass', 'keypass', 'repo_keyalias', 'keydname']
+        if repo_keyalias:
+            to_set.remove('repo_keyalias')
+        if keydname:
+            to_set.remove('keydname')
+        logging.warning('\n' + _('Using existing keystore "{path}"').format(path=keystore)
+                        + '\n' + _('Now set these in config.py:') + ' '
+                        + ', '.join(to_set) + '\n')
+    else:
         password = common.genpassword()
         c = dict(test_config)
         c['keystorepass'] = password

{'commit': 'diff --git a/fdroidserver/init.py b/fdroidserver/init.py\nindex 9fdb5836..9d03e0b9 100644\n--- a/fdroidserver/init.py\n+++ b/fdroidserver/init.py\n@@ -178,6 +178,7 @@ def main():\n                              + \'" does not exist, creating a new keystore there.\')\n     common.write_to_config(test_config, \'keystore\', keystore)\n     repo_keyalias = None\n+    keydname = None\n     if options.repo_keyalias:\n         repo_keyalias = options.repo_keyalias\n         common.write_to_config(test_config, \'repo_keyalias\', repo_keyalias)\n@@ -211,7 +212,16 @@ def main():\n                                    flags=re.MULTILINE)\n             with open(\'opensc-fdroid.cfg\', \'w\') as f:\n                 f.write(opensc_fdroid)\n-    elif not os.path.exists(keystore):\n+    elif os.path.exists(keystore):\n+        to_set = [\'keystorepass\', \'keypass\', \'repo_keyalias\', \'keydname\']\n+        if repo_keyalias:\n+            to_set.remove(\'repo_keyalias\')\n+        if keydname:\n+            to_set.remove(\'keydname\')\n+        logging.warning(\'\\n\' + _(\'Using existing keystore "{path}"\').format(path=keystore)\n+                        + \'\\n\' + _(\'Now set these in config.py:\') + \' \'\n+                        + \', \'.join(to_set) + \'\\n\')\n+    else:\n         password = common.genpassword()\n         c = dict(test_config)\n         c[\'keystorepass\'] = password\n', 'commit_subject': 'init: handle case where keystore.jks is present but config.py is not', 'repo_name': 'f-droid/fdroidserver', 'committer': {'name': 'Hans-Christoph Steiner', 'email': '8800578b51f022c8d8adb9606a8b3db4fedbdac6@eds.org', 'time_sec': '1511985962', 'tz_offset': '60', 'date': {'seconds': '1511985962'}}, 'commit_tree': '1bee586dd406f48a3846523323b6fa426f80da12', 'commit_message': 'init: handle case where keystore.jks is present but config.py is not\n', 'language_name': 'JavaScript', 'license': 'agpl-3.0', 'hunks': '@@ -178,6 +178,7 @@ def main():\n                              + \'" does not exist, creating a new keystore there.\')\n     common.write_to_config(test_config, \'keystore\', keystore)\n     repo_keyalias = None\n+    keydname = None\n     if options.repo_keyalias:\n         repo_keyalias = options.repo_keyalias\n         common.write_to_config(test_config, \'repo_keyalias\', repo_keyalias)\n@@ -211,7 +212,16 @@ def main():\n                                    flags=re.MULTILINE)\n             with open(\'opensc-fdroid.cfg\', \'w\') as f:\n                 f.write(opensc_fdroid)\n-    elif not os.path.exists(keystore):\n+    elif os.path.exists(keystore):\n+        to_set = [\'keystorepass\', \'keypass\', \'repo_keyalias\', \'keydname\']\n+        if repo_keyalias:\n+            to_set.remove(\'repo_keyalias\')\n+        if keydname:\n+            to_set.remove(\'keydname\')\n+        logging.warning(\'\\n\' + _(\'Using existing keystore "{path}"\').format(path=keystore)\n+                        + \'\\n\' + _(\'Now set these in config.py:\') + \' \'\n+                        + \', \'.join(to_set) + \'\\n\')\n+    else:\n         password = common.genpassword()\n         c = dict(test_config)\n         c[\'keystorepass\'] = password\n', 'addition_count': 11, 'deletion_count': 1, 'src_file': 'a/fdroidserver/init.py', 'tgt_file': 'b/fdroidserver/init.py', 'file_extension': '.py', 'before_file': '#!/usr/bin/env python3\n#\n# init.py - part of the FDroid server tools\n# Copyright (C) 2010-2013, Ciaran Gultnieks, ciaran@ciarang.com\n# Copyright (C) 2013-2014 Daniel Martí <mvdan@mvdan.cc>\n# Copyright (C) 2013 Hans-Christoph Steiner <hans@eds.org>\n#\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Affero General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Affero General Public License for more details.\n#\n# You should have received a copy of the GNU Affero General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nimport glob\nimport os\nimport re\nimport shutil\nimport socket\nimport sys\nfrom argparse import ArgumentParser\nimport logging\n\nfrom . import _\nfrom . import common\nfrom .exception import FDroidException\n\nconfig = {}\noptions = None\n\n\ndef disable_in_config(key, value):\n    """Write a key/value to the local config.yml, then comment it out."""\n    import yaml\n\n    with open(\'config.yml\') as f:\n        data = f.read()\n    pattern = r\'\\n[\\s#]*\' + key + r\':.*\'\n    repl = \'\\n#\' + yaml.dump({key: value}, default_flow_style=False)\n    data = re.sub(pattern, repl, data)\n    with open(\'config.yml\', \'w\') as f:\n        f.writelines(data)\n\n\ndef main():\n\n    global options, config\n\n    # Parse command line...\n    parser = ArgumentParser()\n    common.setup_global_opts(parser)\n    parser.add_argument(\n        "-d",\n        "--distinguished-name",\n        default=None,\n        help=_("X.509 \'Distinguished Name\' used when generating keys"),\n    )\n    parser.add_argument(\n        "--keystore",\n        default=None,\n        help=_("Path to the keystore for the repo signing key"),\n    )\n    parser.add_argument(\n        "--repo-keyalias",\n        default=None,\n        help=_("Alias of the repo signing key in the keystore"),\n    )\n    parser.add_argument(\n        "--android-home",\n        default=None,\n        help=_("Path to the Android SDK (sometimes set in ANDROID_HOME)"),\n    )\n    parser.add_argument(\n        "--no-prompt",\n        action="store_true",\n        default=False,\n        help=_("Do not prompt for Android SDK path, just fail"),\n    )\n    options = parser.parse_args()\n\n    fdroiddir = os.getcwd()\n    test_config = dict()\n    examplesdir = common.get_examples_dir()\n    common.fill_config_defaults(test_config)\n\n    # track down where the Android SDK is, the default is to use the path set\n    # in ANDROID_HOME if that exists, otherwise None\n    if options.android_home is not None:\n        test_config[\'sdk_path\'] = options.android_home\n    elif not common.test_sdk_exists(test_config):\n        # if neither --android-home nor the default sdk_path\n        # exist, prompt the user using platform-specific default\n        # and if the user leaves it blank, ignore and move on.\n        default_sdk_path = \'\'\n        if sys.platform in (\'win32\', \'cygwin\'):\n            p = os.path.join(\n                os.getenv(\'USERPROFILE\'), \'AppData\', \'Local\', \'Android\', \'android-sdk\'\n            )\n        elif sys.platform == \'darwin\':\n            # on OSX, Homebrew is common and has an easy path to detect\n            p = \'/usr/local/opt/android-sdk\'\n        elif os.path.isdir(\'/usr/lib/android-sdk\'):\n            # if the Debian packages are installed, suggest them\n            p = \'/usr/lib/android-sdk\'\n        else:\n            p = \'/opt/android-sdk\'\n        if os.path.exists(p):\n            default_sdk_path = p\n            test_config[\'sdk_path\'] = default_sdk_path\n\n        if not common.test_sdk_exists(test_config):\n            del (test_config[\'sdk_path\'])\n            while not options.no_prompt:\n                try:\n                    s = input(\n                        _(\'Enter the path to the Android SDK (%s) here:\\n> \')\n                        % default_sdk_path\n                    )\n                except KeyboardInterrupt:\n                    print(\'\')\n                    sys.exit(1)\n                if re.match(r\'^\\s*$\', s) is not None:\n                    test_config[\'sdk_path\'] = default_sdk_path\n                else:\n                    test_config[\'sdk_path\'] = s\n                if common.test_sdk_exists(test_config):\n                    break\n                default_sdk_path = \'\'\n\n    if test_config.get(\'sdk_path\') and not common.test_sdk_exists(test_config):\n        raise FDroidException(\n            _("Android SDK not found at {path}!").format(path=test_config[\'sdk_path\'])\n        )\n\n    if not os.path.exists(\'config.yml\') and not os.path.exists(\'config.py\'):\n        # \'metadata\' and \'tmp\' are created in fdroid\n        if not os.path.exists(\'repo\'):\n            os.mkdir(\'repo\')\n        example_config_yml = os.path.join(examplesdir, \'config.yml\')\n        if os.path.exists(example_config_yml):\n            shutil.copyfile(example_config_yml, \'config.yml\')\n        else:\n            from pkg_resources import get_distribution\n\n            versionstr = get_distribution(\'fdroidserver\').version\n            if not versionstr:\n                versionstr = \'master\'\n            with open(\'config.yml\', \'w\') as fp:\n                fp.write(\'# see https://gitlab.com/fdroid/fdroidserver/blob/\')\n                fp.write(versionstr)\n                fp.write(\'/examples/config.yml\\n\')\n        os.chmod(\'config.yml\', 0o0600)\n        # If android_home is None, test_config[\'sdk_path\'] will be used and\n        # "$ANDROID_HOME" may be used if the env var is set up correctly.\n        # If android_home is not None, the path given from the command line\n        # will be directly written in the config.\n        if \'sdk_path\' in test_config:\n            common.write_to_config(test_config, \'sdk_path\', options.android_home)\n    else:\n        logging.warning(\n            \'Looks like this is already an F-Droid repo, cowardly refusing to overwrite it...\'\n        )\n        logging.info(\'Try running `fdroid init` in an empty directory.\')\n        raise FDroidException(\'Repository already exists.\')\n\n    # now that we have a local config.yml, read configuration...\n    config = common.read_config(options)\n\n    # the NDK is optional and there may be multiple versions of it, so it\'s\n    # left for the user to configure\n\n                             + \'" does not exist, creating a new keystore there.\')\n    common.write_to_config(test_config, \'keystore\', keystore)\n    repo_keyalias = None\n    if options.repo_keyalias:\n        repo_keyalias = options.repo_keyalias\n        common.write_to_config(test_config, \'repo_keyalias\', repo_keyalias)\n    if options.keystore:\n        keystore = os.path.abspath(options.keystore)\n        if options.keystore == \'NONE\':\n            keystore = options.keystore\n        else:\n            keystore = os.path.abspath(options.keystore)\n            if not os.path.exists(keystore):\n                logging.info(\n                    \'"\' + keystore + \'" does not exist, creating a new keystore there.\'\n                )\n    common.write_to_config(test_config, \'keystore\', keystore)\n    repo_keyalias = None\n    keydname = None\n    if options.repo_keyalias:\n        repo_keyalias = options.repo_keyalias\n        common.write_to_config(test_config, \'repo_keyalias\', repo_keyalias)\n    if options.distinguished_name:\n        keydname = options.distinguished_name\n        common.write_to_config(test_config, \'keydname\', keydname)\n    if keystore == \'NONE\':  # we\'re using a smartcard\n        common.write_to_config(\n            test_config, \'repo_keyalias\', \'1\'\n        )  # seems to be the default\n        disable_in_config(\'keypass\', \'never used with smartcard\')\n        common.write_to_config(\n            test_config,\n            \'smartcardoptions\',\n                                   flags=re.MULTILINE)\n            with open(\'opensc-fdroid.cfg\', \'w\') as f:\n                f.write(opensc_fdroid)\n    elif not os.path.exists(keystore):\n        password = common.genpassword()\n        c = dict(test_config)\n        c[\'keystorepass\'] = password\n                if len(files) > 0:\n                    opensc_so = files[0]\n                else:\n                    opensc_so = \'/usr/lib/opensc-pkcs11.so\'\n                    logging.warning(\n                        \'No OpenSC PKCS#11 module found, \'\n                        + \'install OpenSC then edit "opensc-fdroid.cfg"!\'\n                    )\n            with open(\'opensc-fdroid.cfg\', \'w\') as f:\n                f.write(\'name = OpenSC\\nlibrary = \')\n                f.write(opensc_so)\n                f.write(\'\\n\')\n        logging.info(\n            "Repo setup using a smartcard HSM. Please edit keystorepass and repo_keyalias in config.yml."\n        )\n        logging.info(\n            "If you want to generate a new repo signing key in the HSM you can do that with \'fdroid update "\n            "--create-key\'."\n        )\n    elif os.path.exists(keystore):\n        to_set = [\'keystorepass\', \'keypass\', \'repo_keyalias\', \'keydname\']\n        if repo_keyalias:\n            to_set.remove(\'repo_keyalias\')\n        if keydname:\n            to_set.remove(\'keydname\')\n        logging.warning(\n            \'\\n\'\n            + _(\'Using existing keystore "{path}"\').format(path=keystore)\n            + \'\\n\'\n            + _(\'Now set these in config.yml:\')\n            + \' \'\n            + \', \'.join(to_set)\n            + \'\\n\'\n        )\n    else:\n        password = common.genpassword()\n        c = dict(test_config)\n        c[\'keystorepass\'] = password\n        c[\'keypass\'] = password\n        c[\'repo_keyalias\'] = socket.getfqdn()\n        c[\'keydname\'] = \'CN=\' + c[\'repo_keyalias\'] + \', OU=F-Droid\'\n        common.write_to_config(test_config, \'keystorepass\', password)\n        common.write_to_config(test_config, \'keypass\', password)\n        common.write_to_config(test_config, \'repo_keyalias\', c[\'repo_keyalias\'])\n        common.write_to_config(test_config, \'keydname\', c[\'keydname\'])\n        common.genkeystore(c)\n\n    msg = \'\\n\'\n    msg += _(\'Built repo based in "%s" with this config:\') % fdroiddir\n    msg += \'\\n\\n  Android SDK:\\t\\t\\t\' + config[\'sdk_path\']\n    msg += \'\\n  \' + _(\'Keystore for signing key:\\t\') + keystore\n    if repo_keyalias is not None:\n        msg += \'\\n  Alias for key in store:\\t\' + repo_keyalias\n    msg += \'\\n\\n\'\n    msg += (\n        _(\n            \'\'\'To complete the setup, add your APKs to "%s"\nthen run "fdroid update -c; fdroid update".  You might also want to edit\n"config.yml" to set the URL, repo name, and more.  You should also set up\na signing key (a temporary one might have been automatically generated).\n\nFor more info: https://f-droid.org/docs/Setup_an_F-Droid_App_Repo\nand https://f-droid.org/docs/Signing_Process\'\'\'\n        )\n        % os.path.join(fdroiddir, \'repo\')\n    )\n    logging.info(msg)\n', 'message': 'init: handle case where keystore.jks is present but config.py is not\n', 'author_name': 'Hans-Christoph Steiner', 'lang': 'py'}