示例#1
0
    def get_git_url(self):
        """
        Returns git url  by `git config --get remote.origin.url`

        If the provided bundle inherits properties from a .xo file, then
        using git to extract commits is not sensible. A developer can tweak
        this by setting environment variable ASLOv4_ACTIVITY_XO_GITURL to
        a get the remote origin in a *.git file

        For example, if the app is called Pippy Activity, name the file
        org.laptop.Pippy.log, where org.laptop.Pippy is the bundle name.

        use
        $ git config --get remote.origin.url > org.laptop.Pippy.git

        Finally place these information in a folder, say `foobar`
        then

        $ export ASLOv4_ACTIVITY_XO_GITURL="/path/to/foobar"
        $ aslo4 --parameters-here

        This will automatically parse the information in the .git files
        inherited from git and then annotate "Source Code" button with
        the right link.
        """

        if self.is_xo:
            if not os.getenv("ASLOv4_ACTIVITY_XO_GITURL"):
                return  # bundles does not have .git directory, skip
            saas_activity_xo_giturl = os.path.join(
                os.getenv("ASLOv4_ACTIVITY_XO_GITURL"),
                "{}.git".format(self.get_bundle_id())
            )
            if not os.path.exists(saas_activity_xo_giturl):
                return
            with open(saas_activity_xo_giturl, 'r') as r:
                url = r.read()
            return url
        url_process = subprocess.Popen(
            _s('{git} -C {path} config --get remote.origin.url'.format(
                git=get_executable_path('git'),
                path=self.get_activity_dir()
            )),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        ecode = url_process.wait(timeout=5)
        if ecode != 0:
            # process did not complete successfully
            # hence no git url
            return None
        out, _ = url_process.communicate()
        url = out.decode().split('\n')
        if len(url) >= 1:
            return url[0]
示例#2
0
    def do_install_bundle(self, system=False):
        """
        Install the activity to a user level, if system
        keyword argument is provided to be False,
        otherwise installed to system `/usr` level
        :return:
        """
        # get optional flags
        flags = "" if system else "--user"

        # check if the current activity is already a bundle
        if self.is_xo:
            # I am a bundle. Install it by sugar-install-build provided
            # by the sugar-toolkit-gtk3 package
            sugar_install_bundle_exe = get_executable_path(
                "sugar-install-bundle")
            proc = subprocess.Popen(
                _s("{exe} {activity_xo} {flag}".format(
                    exe=sugar_install_bundle_exe,
                    activity_xo=self.activity_path,
                    flag=flags,
                )),
                cwd=self.get_activity_dir(),
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE,
            )
            exit_code = wait_for_process_completion(proc, retry=True)
            out, err = proc.communicate()
            return exit_code, out.decode(), err.decode()

        python_exe = get_executable_path(
            "python3", False) or get_executable_path("python")
        proc = subprocess.Popen(
            _s("{} setup.py install {}".format(python_exe, flags)),
            cwd=self.get_activity_dir(),
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE,
        )
        exit_code = proc.wait(timeout=120)
        out, err = proc.communicate()
        return exit_code, out.decode(), err.decode()
示例#3
0
    def create_authors_log_file(self):
        """
        Creates the log file generated by

        $ git -P log --pretty=format:"%an"

        and returns it as string

        This can be used programmatically to create log files
        from many clones. A sample code is provided below

        >>> from aslo4.generator import SaaSBuild
        >>> sb = SaaSBuild()
        >>> all_activities = sb.list_activities()
        >>>
        >>> def write_log_file(bundle_name, data):
        ...     with open(os.path.join('/foo/bar', "{}.log".format(
        ...         bundle_name))  # noqa:
        ...     ) as w:
        ...         w.write(data)  # noqa:
        >>>
        >>> for activity in all_activities:
        ...     write_log_file(
        ...         activity.get_bundle_id(),
        ...         activity.create_authors_log_file()
        ...     )
        :return: string of all the authors
        :rtype: str
        """
        author_raw = subprocess.Popen(
            _s('{git} -C {activity_path} -P log --pretty=format:"%an"'.format(
                git=get_executable_path("git"),
                activity_path=self.get_activity_dir(),
            )),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        author_raw.wait(timeout=10)
        out, _ = author_raw.communicate()
        authors = out.decode()
        return authors
示例#4
0
    def do_generate_bundle(self,
                           override_dist_xo=False,
                           entrypoint_build_command=None,
                           build_command_chdir=False,
                           checkout_latest_tag=False):
        """
        Generates a .xo file for the activities
        by spawning a subprocess

        Some additional pro level features ;)

        The script file supports python f-strings
        Pass the parameters as named {name}, {v} to get name and version
        appropriately

        Some important format specifiers
        {name} : Activity Name
        {v} : Activity version
        {activity_dir} : the path of the Activity,
        i.e ~/FractionBounce.Activity
        {icon_path}: the path of the icon path

        Make sure you add a cd (change directory) function within the
        shell / python script
        The script is run relative to path of execution.
        To change location each time before command execution,
        pass --build-chdir
        :return: Tuple (e_code, stdout, stderr)

        """
        if self.is_xo:
            # I am already a xo. Why build me? duh
            return 0, '[xo] Already Built.', ''

        if override_dist_xo and not entrypoint_build_command:
            raise ValueError("entrypoint_build_command was not provided")

        if checkout_latest_tag and not self.is_xo:
            # checkout the latest tag on the activity build
            try:
                git_checkout_latest_tag(self.get_activity_dir())
            except Exception as e:
                cprint(
                    "WARN: git checkout to latest tag failed. E: {}".format(e),
                    "yellow")

        current_path_ = os.getcwd()
        if entrypoint_build_command and isinstance(entrypoint_build_command,
                                                   str):
            # read the shell / python script
            with open(entrypoint_build_command, 'r') as r:
                commands_to_pre_execute = r.read()

            # change dir, if necessary:
            if build_command_chdir:
                os.chdir(self.get_activity_dir())

            # execute the commands, format the f-strings before execution
            exit_code = os.system(
                commands_to_pre_execute.format(
                    name=self.get_name(),
                    v=self.get_version(),
                    activity_dir=self.get_activity_dir(),
                    icon_path=self.get_icon_path()))

            # restore the current working directory in the case directory was
            # changed
            if build_command_chdir:
                os.chdir(current_path_)

            if override_dist_xo:
                return exit_code, '', ''

        python3_exe = get_executable_path(
            'python3', False) or get_executable_path('python')
        python2_exe = get_executable_path(
            'python2', False) or get_executable_path('python')

        # check the type of activity
        if self.get_activity_type() == 'python2':
            # in the case the software to be used is sugar-activity
            # use python2 in that case.
            python_exe = python2_exe
        else:
            # use the python3 version to build all the rest of the
            # types of the activities
            python_exe = python3_exe

        proc = subprocess.Popen(_s("{} setup.py dist_xo".format(python_exe)),
                                cwd=self.get_activity_dir(),
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE)

        # wait for process to complete
        exit_code = wait_for_process_completion(proc)
        if exit_code:
            # process did not complete successfully
            return exit_code, '', ''

        # read the stdout and stderr
        out, err = proc.communicate()

        if not exit_code:
            dist_path = os.path.join(self.get_activity_dir(), 'dist')
            bundle = get_latest_bundle(dist_path)
            if bundle:
                self.set_bundle_path(bundle)

        if checkout_latest_tag and not self.is_xo:
            # restore the branch to master
            git_checkout(self.get_activity_dir())

        return exit_code, out.decode(), err.decode()