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]
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()
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
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()