Example #1
0
    def run(self, args):
        os.environ["PATH"] = "{}:{}".format(
            os.path.join(self.sdk_path(args), "arm-cs-tools", "bin"), os.environ["PATH"]
        )

        cmdLine = self.waf_path(args) + " " + self.waf_cmds
        retval = subprocess.call(cmdLine, shell=True)

        # If an error occurred, we need to do some sleuthing to determine a
        # cause. This allows the caller to post more useful information to
        # analytics. We normally don't capture stdout and stderr using Poepn()
        # because you lose the nice color coding produced when the command
        # outputs to a terminal directly.
        #
        # But, if an error occurs, let's run it again capturing the output
        #  so we can determine the cause

        if retval:
            cmdArgs = cmdLine.split()
            try:
                cmdObj = create_sh_cmd_obj(cmdArgs[0])
                output = cmdObj(*cmdArgs[1:])
                stderr = output.stderr
            except sh.ErrorReturnCode as e:
                stderr = e.stderr

                # Look for common problems
            if "Could not determine the compiler version" in stderr:
                raise NoCompilerException

            elif "region `APP' overflowed" in stderr:
                raise AppTooBigException

            else:
                raise BuildErrorException

        elif args.command == "build":
            # No error building. Send up app memory usage and resource usage
            #  up to analytics
            # Read in the appinfo.json to get the list of resources
            try:
                appInfo = json.load(open("appinfo.json"))
                self._send_memory_usage(args, appInfo)
                self._send_resource_usage(args, appInfo)
                self._send_line_counts(args, appInfo)
                hasJS = os.path.exists(os.path.join("src", "js"))
                PblAnalytics.code_has_java_script_evt(uuid=appInfo["uuid"], hasJS=hasJS)
            except Exception as e:
                logging.error("Exception occurred collecting app analytics: " "%s" % str(e))
                logging.debug(traceback.format_exc())

        return 0
Example #2
0
    def _send_line_counts(self, args, appInfo):
        """ Send app line counts up to analytics

        Parameters:
        --------------------------------------------------------------------
        args: the args passed to the run() method
        appInfo: the applications appInfo
        """

        c_line_count = 0
        js_line_count = 0
        if os.path.exists("src"):
            c_line_count += self._count_lines("src", [".h", ".c"])
            js_line_count += self._count_lines("src", [".js"])

        PblAnalytics.code_line_count_evt(uuid=appInfo["uuid"], c_line_count=c_line_count, js_line_count=js_line_count)
Example #3
0
    def _send_resource_usage(self, args, appInfo):
        """ Send app resource usage up to analytics

        Parameters:
        --------------------------------------------------------------------
        args: the args passed to the run() method
        appInfo: the applications appInfo
        """

        # Collect the number and total size of each class of resource:
        resCounts = {"raw": 0, "image": 0, "font": 0}
        resSizes = {"raw": 0, "image": 0, "font": 0}

        for resDict in appInfo["resources"]["media"]:
            if resDict["type"] in ["png", "png-trans"]:
                resource_type = "image"
            elif resDict["type"] in ["font"]:
                resource_type = "font"
            elif resDict["type"] in ["raw"]:
                resource_type = "raw"
            else:
                raise RuntimeError("Unsupported resource type %s" % (resDict["type"]))

            # Look for the generated blob in the build/resource directory.
            # As far as we can tell, the generated blob always starts with
            # the original filename and adds an extension to it, or (for
            # fonts), a name and extension.
            (dirName, fileName) = os.path.split(resDict["file"])
            dirToSearch = os.path.join("build", "resources", dirName)
            found = False
            size = 0

            for name in os.listdir(dirToSearch):
                if name.startswith(fileName):
                    size = os.path.getsize(os.path.join(dirToSearch, name))
                    found = True
                    break
            if not found:
                raise RuntimeError("Could not find generated resource " "corresponding to %s." % (resDict["file"]))

            resCounts[resource_type] += 1
            resSizes[resource_type] += size

        # Send the stats now
        PblAnalytics.res_sizes_evt(uuid=appInfo["uuid"], resCounts=resCounts, resSizes=resSizes)
Example #4
0
    def _send_memory_usage(self, args, appInfo):
        """ Send app memory usage to analytics

        Parameters:
        --------------------------------------------------------------------
        args: the args passed to the run() method
        appInfo: the applications appInfo
        """

        cmdName = "arm_none_eabi_size"
        cmdArgs = [os.path.join("build", "pebble-app.elf")]
        try:
            output = sh.arm_none_eabi_size(*cmdArgs)
            (textSize, dataSize, bssSize) = [int(x) for x in output.stdout.splitlines()[1].split()[:3]]
            sizeDict = {"text": textSize, "data": dataSize, "bss": bssSize}
            PblAnalytics.code_size_evt(uuid=appInfo["uuid"], segSizes=sizeDict)
        except sh.ErrorReturnCode as e:
            logging.error(
                "command %s %s failed. stdout: %s, stderr: %s" % (cmdName, " ".join(cmdArgs), e.stdout, e.stderr)
            )
        except sh.CommandNotFound as e:
            logging.error("The command %s could not be found. Could not " "collect memory usage analytics." % e.message)
Example #5
0
    def run_action(self, action, args):
        # Find the extension that was called
        command = [x for x in self.commands if x.name == args.command][0]

        try:
            retval = command.run(args)
            if retval:
                PblAnalytics.cmd_fail_evt(args.command, 'unknown error')
            else:
                cmdName = args.command
                if cmdName == 'install' and args.logs is True:
                    cmdName = 'install --logs'
                PblAnalytics.cmd_success_evt(cmdName)
            return retval

        except libpebble.PebbleError as e:
            PblAnalytics.cmd_fail_evt(args.command, 'pebble error')
            if args.debug:
                raise e
            else:
                logging.error(e)
                return 1

        except ConfigurationException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'configuration error')
            logging.error(e)
            return 1

        except InvalidProjectException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'invalid project')
            logging.error("This command must be run from a Pebble project "
                          "directory")
            return 1

        except OutdatedProjectException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'outdated project')
            logging.error("The Pebble project directory is using an outdated "
                          "version of the SDK!")
            logging.error("Try running `pebble convert-project` to update the "
                          "project")
            return 1

        except NoCompilerException as e:
            PblAnalytics.missing_tools_evt()
            logging.error("The compiler/linker tools could not be found. "
                          "Ensure that the arm-cs-tools directory is present "
                          "in the Pebble SDK directory (%s)" %
                          PblCommand().sdk_path(args))
            return 1

        except BuildErrorException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'compilation error')
            logging.error("A compilation error occurred")
            return 1

        except AppTooBigException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'application too big')
            logging.error("The built application is too big")
            return 1

        except Exception as e:
            PblAnalytics.cmd_fail_evt(args.command,
                                      'unhandled exception: %s' % str(e))
            logging.error(str(e))
            return 1
Example #6
0
import pebble.PblAnalytics as PblAnalytics

# Catch any missing python dependencies so we can send an event to analytics
try:
    import pebble as libpebble
    from pebble.PblProjectCreator import (PblProjectCreator,
                                          InvalidProjectException,
                                          OutdatedProjectException)
    from pebble.PblProjectConverter import PblProjectConverter
    from pebble.PblBuildCommand import PblBuildCommand, PblCleanCommand
    from pebble.LibPebblesCommand import *
except Exception as e:
    logging.basicConfig(format='[%(levelname)-8s] %(message)s',
                        level=logging.DEBUG)
    PblAnalytics.missing_python_dependency_evt(str(e))
    raise


class PbSDKShell:
    commands = []

    def __init__(self):
        self.commands.append(PblProjectCreator())
        self.commands.append(PblProjectConverter())
        self.commands.append(PblBuildCommand())
        self.commands.append(PblCleanCommand())
        self.commands.append(PblInstallCommand())
        self.commands.append(PblInstallFWCommand())
        self.commands.append(PblPingCommand())
        self.commands.append(PblListCommand())
Example #7
0
    def run_action(self, action, args):
        # Find the extension that was called
        command = [x for x in self.commands if x.name == args.command][0]

        try:
            retval = command.run(args)
            if retval:
                PblAnalytics.cmd_fail_evt(args.command, 'unknown error')
            else:
                cmdName = args.command
                if cmdName == 'install' and args.logs is True:
                    cmdName = 'install --logs'
                PblAnalytics.cmd_success_evt(cmdName)
            return retval
                
        except libpebble.PebbleError as e:
            PblAnalytics.cmd_fail_evt(args.command, 'pebble error')
            if args.debug:
                raise e
            else:
                logging.error(e)
                return 1
            
        except ConfigurationException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'configuration error')
            logging.error(e)
            return 1
        
        except InvalidProjectException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'invalid project')
            logging.error("This command must be run from a Pebble project "
                          "directory")
            return 1
        
        except OutdatedProjectException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'outdated project')
            logging.error("The Pebble project directory is using an outdated "
                          "version of the SDK!")
            logging.error("Try running `pebble convert-project` to update the "
                          "project")
            return 1
        
        except NoCompilerException as e:
            PblAnalytics.missing_tools_evt()
            logging.error("The compiler/linker tools could not be found. "
                          "Ensure that the arm-cs-tools directory is present "
                          "in the Pebble SDK directory (%s)" % 
                          PblCommand().sdk_path(args))
            return 1
        
        except BuildErrorException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'compilation error')
            logging.error("A compilation error occurred")
            return 1
        
        except AppTooBigException as e:
            PblAnalytics.cmd_fail_evt(args.command, 'application too big')
            logging.error("The built application is too big")
            return 1
        
        except Exception as e:
            PblAnalytics.cmd_fail_evt(args.command, 'unhandled exception: %s' %
                                 str(e))
            logging.error(str(e))
            return 1
Example #8
0
import pebble.PblAnalytics as PblAnalytics

# Catch any missing python dependencies so we can send an event to analytics
try:
    import pebble as libpebble
    from pebble.PblProjectCreator   import (PblProjectCreator, 
                                            InvalidProjectException, 
                                            OutdatedProjectException)
    from pebble.PblProjectConverter import PblProjectConverter
    from pebble.PblBuildCommand     import PblBuildCommand, PblCleanCommand
    from pebble.LibPebblesCommand   import *
except Exception as e:
    logging.basicConfig(format='[%(levelname)-8s] %(message)s', 
                    level = logging.DEBUG)
    PblAnalytics.missing_python_dependency_evt(str(e))
    raise

class PbSDKShell:
    commands = []

    def __init__(self):
        self.commands.append(PblProjectCreator())
        self.commands.append(PblProjectConverter())
        self.commands.append(PblBuildCommand())
        self.commands.append(PblCleanCommand())
        self.commands.append(PblInstallCommand())
        self.commands.append(PblInstallFWCommand())
        self.commands.append(PblPingCommand())
        self.commands.append(PblListCommand())
        self.commands.append(PblRemoteCommand())