Esempio n. 1
0
def _cmd_init(args, extra=None):
    if os.path.isfile(
            os.path.join(JustUpdateConstants.REPO_FOLDER,
                         "config.ju")) or os.path.isdir(
                             JustUpdateConstants.REPO_FOLDER):
        logging.warning(
            "A JustUpdate repository already exists at this location.")
        return True

    # setup a new repo.
    app_name = prompt("Application Name:", "MyAwezomeApp")
    app_author = prompt("Application Author:", "MyAwesomeCompany")
    update_url = prompt("Url to ping for updates:")
    client_config_dir = prompt(
        "Where to place the client_config.py file (used by your application): ",
        default=".")

    if update_url.endswith("/") == False:
        update_url += "/"
    logging.info("Creating folder structure.")
    os.makedirs(JustUpdateConstants.REPO_FOLDER)
    logging.info("Creating config.")
    c = Config()
    c.set("app_name", app_name)
    c.set("app_author", app_author)
    c.set("update_url", update_url)
    c.save(os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))
    logging.info("Saving config.")
    logging.info("Copying templates.")
    shutil.copytree(
        os.path.join(JustUpdateConstants.MODULE_FOLDER, "templates"),
        os.path.join(JustUpdateConstants.REPO_FOLDER, "templates"))
    logging.info("Templates copied.")
    logging.info("Creating client config.")
    client_config_data = """class ClientConfig():
	app_name = "{}"
	app_author = "{}"
	update_url = "{}"
""".format(app_name, app_author, update_url)
    with open(os.path.join(client_config_dir, "client_config.py"), "w") as cc:
        cc.write(client_config_data)
    logging.info("Initialization done.")
Esempio n. 2
0
def prepare_template(version):
    config = Config()
    config.load(os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))
    cmd = getattr(sys.modules[__name__],
                  "_prepare_template_{}".format(get_platform_name_short()))
    return cmd(version, config)
Esempio n. 3
0
 def __init__(self):
     self.config = Config()
     self.config.load(
         os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))
Esempio n. 4
0
class Builder():
    def __init__(self):
        self.config = Config()
        self.config.load(
            os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))

    def clean(self):
        try:
            shutil.rmtree(os.path.join(JustUpdateConstants.REPO_FOLDER,
                                       "work"))
        except FileNotFoundError:
            pass  # It's ok if the folder doesn't exist.
        cmd = getattr(self, f"_clean_{get_platform_name_short()}")
        return cmd()

    def _clean_win(self):
        try:
            shutil.rmtree(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win"))
        except FileNotFoundError:
            pass  # It's ok if the folder doesn't exist.

    def _clean_mac(self):
        try:
            shutil.rmtree(
                os.path.join(os.getcwd(), JustUpdateConstants.REPO_FOLDER,
                             "dist", "mac"))
        except FileNotFoundError:
            pass  # It's ok if the folder doesn't exist.
        try:
            shutil.rmtree(
                os.path.join(os.getcwd(), JustUpdateConstants.REPO_FOLDER,
                             "dist",
                             "{}.app".format(self.config.get("app_name"))))
        except FileNotFoundError:
            pass  # It's ok if the folder doesn't exist.
        try:
            os.remove(
                os.path.join(os.getcwd(), JustUpdateConstants.REPO_FOLDER,
                             "dist", "mac"))
        except FileNotFoundError:
            pass  # It's ok if the folder doesn't exist.

    def build(self, args, extra_args):
        cmd = [
            "pyinstaller", "--distpath",
            os.path.join(os.getcwd(), JustUpdateConstants.REPO_FOLDER,
                         "dist"), "--workpath",
            os.path.join(os.getcwd(), JustUpdateConstants.REPO_FOLDER, "work"),
            "-y", args
        ] + extra_args
        executor = CommandExecutor()
        logging.info("Building.")
        result, stdout = executor.execute(cmd, CommandType.RAW)
        if result > 0:  # error
            print(stdout)
            logging.error("Please correct the errors above and try again.")
        else:
            logging.info("Build completed.")
        return result == 0

    def post_build(self):
        cmd = getattr(self, f"_post_build_{get_platform_name_short()}")
        return cmd()

    def _post_build_win(self):
        logging.info("Checking build integrity")
        if os.path.isdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "win")) == False:
            logging.error("Unable to find the build fonder.")
        app_name = self.config.get("app_name")
        # First look for .exe.manifest, and rename that if it exists.
        try:
            os.rename(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win",
                             "win.exe.manifest"),
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win",
                             f"{app_name}.exe.manifest"))
        except:
            pass
        # then try for the exe itself.
        try:
            os.rename(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win",
                             "win.exe"),
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win",
                             f"{app_name}.exe"))
        except:
            raise
        logging.info("Done")

    def _post_build_mac(self):
        if os.path.isfile(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "mac")):  # asume unix executable.
            raise ValueError(
                "--onefile is not supported at the moment. For now the only mode supported are --onedir --windowed (creating an application bundle)"
            )
            return
        if os.path.isdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "mac.app")):  # asume mac application bundle.
            os.rename(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "mac.app", "Contents", "MacOS", "mac"),
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "mac.app", "Contents", "MacOS",
                             self.config.get("app_name")))
            os.rename(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "mac.app"),
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "{}.app".format(self.config.get("app_name"))))
            # also temporary update the plist file (note it will be overwritten in commit, only reason to do this, is so the end developer can test the app before commiting).
            with open(os.path.join(
                    JustUpdateConstants.REPO_FOLDER, "dist",
                    "{}.app".format(self.config.get("app_name")), "Contents",
                    "Info.plist"),
                      encoding="utf-8") as f:
                plist_data = f.readlines()
            new_plist_data = []
            for d in plist_data:
                if "mac" in d:
                    new_plist_data.append(
                        d.replace("mac", self.config.get("app_name")))
                else:
                    new_plist_data.append(d)
            with open(os.path.join(
                    JustUpdateConstants.REPO_FOLDER, "dist",
                    "{}.app".format(self.config.get("app_name")), "Contents",
                    "Info.plist"),
                      "w",
                      encoding="utf-8") as f:
                for d in new_plist_data:
                    f.write(d)
Esempio n. 5
0
 def __init__(self, version):
     self.config = Config()
     self.config.load(
         os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))
     self.version = Version(version)
     self.executor = CommandExecutor()
Esempio n. 6
0
class Committer():
    def __init__(self, version):
        self.config = Config()
        self.config.load(
            os.path.join(JustUpdateConstants.REPO_FOLDER, "config.ju"))
        self.version = Version(version)
        self.executor = CommandExecutor()

    def setup(self):
        if os.path.isdir(os.path.join(JustUpdateConstants.REPO_FOLDER,
                                      "new")) == False:
            os.makedirs(os.path.join(JustUpdateConstants.REPO_FOLDER, "new"))
        if os.path.isdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER,
                             "deploy")) == False:
            os.makedirs(os.path.join(JustUpdateConstants.REPO_FOLDER,
                                     "deploy"))

    def insure_build_availability(self):
        cmd = getattr(
            self,
            "_insure_build_availability_{}".format(get_platform_name_short()))
        return cmd()

    def produce_executable(self):
        cmd = getattr(
            self, "_produce_executable_{}".format(get_platform_name_short()))
        return cmd()

    def create_metadata(self):
        cmd = getattr(self,
                      "_create_metadata_{}".format(get_platform_name_short()))
        return cmd()

    def finalize(self):
        cmd = getattr(self, "_finalize_{}".format(get_platform_name_short()))
        return cmd()

    def _insure_build_availability_win(self):
        if os.path.isdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "win")) == False:
            return False
        if not os.listdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win")):
            return False
        return True

    def _insure_build_availability_mac(self):
        if not os.path.isdir(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "{}.app".format(self.config.get("app_name")))):
            return False
        return True

    def _produce_executable_win(self):
        tmp = template.prepare_template(self.version)
        cmd = ["makensis", "/V1", "-"]
        result, stdout = self.executor.execute(cmd, CommandType.RAW, stdin=tmp)
        if result != 0:
            print(stdout)
            logging.error("Please correct the errors above and try again.")
            return False
        return True

    def _produce_executable_mac(self):
        logging.debug("Updating Info.plist and installation scripts.")
        tmp = template.prepare_template(self.version)
        logging.debug("Assembling pkg installer.")
        cmd = [
            "productbuild", "--scripts",
            os.path.join(JustUpdateConstants.REPO_FOLDER, "templates", "mac",
                         "scripts"), "--component",
            os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                         "{}.app".format(self.config.get("app_name"))),
            "/Applications",
            os.path.join(
                JustUpdateConstants.REPO_FOLDER, "new",
                "{0}-{1}.pkg".format(self.config.get("app_name"),
                                     self.version.to_string()))
        ]
        result, stdout = self.executor.execute(cmd, CommandType.RAW)
        if result != 0:
            print(stdout)
            logging.error("Please correct the errors above and try again.")
            return False
        return True

    def _create_metadata_win(self):
        logging.info("Calculating checksum.")
        checksum = data_manager.calculate_checksum(
            os.path.join(
                JustUpdateConstants.REPO_FOLDER, "new",
                "{0}-{1}.exe".format(self.config.get("app_name"),
                                     self.version.to_string())))
        logging.info("Looking for existing metadata.")
        md = MetaData()
        md.apply_metadata(md.load())
        md.add_metadata(
            "{0}-{1}.exe".format(self.config.get("app_name"),
                                 self.version.to_string()), checksum,
            self.version.to_string())
        logging.info("Saving updated metadata.")
        md.save(
        )  # The updated metadata is saved to "ju-repo/deploy/metadata.ju".
        return True

    def _create_metadata_mac(self):
        logging.info("Calculating checksum.")
        checksum = data_manager.calculate_checksum(
            os.path.join(
                JustUpdateConstants.REPO_FOLDER, "new",
                "{0}-{1}.pkg".format(self.config.get("app_name"),
                                     self.version.to_string())))
        logging.info("Looking for existing metadata.")
        md = MetaData()
        md.apply_metadata(md.load())
        md.add_metadata(
            "{0}-{1}.pkg".format(self.config.get("app_name"),
                                 self.version.to_string()), checksum,
            self.version.to_string())
        logging.info("Saving updated metadata.")
        md.save(
        )  # The updated metadata is saved to "ju-repo/deploy/metadata.ju".
        return True

    def _finalize_win(self):
        logging.info("Moving executable.")
        shutil.move(
            os.path.join(
                JustUpdateConstants.REPO_FOLDER, "new",
                "{0}-{1}.exe".format(self.config.get("app_name"),
                                     self.version.to_string())),
            os.path.join(JustUpdateConstants.REPO_FOLDER, "deploy"))
        #cleanup ju-repo/dist/win
        shutil.rmtree(
            os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "win"))

    def _finalize_mac(self):
        logging.info("Moving executable.")
        shutil.move(
            os.path.join(
                JustUpdateConstants.REPO_FOLDER, "new",
                "{0}-{1}.pkg".format(self.config.get("app_name"),
                                     self.version.to_string())),
            os.path.join(JustUpdateConstants.REPO_FOLDER, "deploy"))
        #cleanup ju-repo/dist/mac
        try:
            shutil.rmtree(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist", "mac"))
        except:
            pass
        try:
            shutil.rmtree(
                os.path.join(JustUpdateConstants.REPO_FOLDER, "dist",
                             "{}.app".format(self.config.get("app_name"))))
        except:
            pass