示例#1
0
    def validate(self):
        p = self.target_dir / ".build.manifest"
        if not p.exists():
            return [], [], []
        ignorer = utils.ignore_matcher(DEFAULT_IGNORES)
        a, c, d = utils.delta_signatures(p, ignorer)

        for f in a:
            log.warn(
                "Added unexpected file, should be in a base layer: %s", f)
        for f in c:
            log.warn(
                "Changed file owned by another layer: %s", f)
        for f in d:
            log.warn(
                "Deleted a file owned by another layer: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise ValueError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")
        return a, c, d
示例#2
0
def inspect(charm, force_styling=False):
    tw = utils.TermWriter(force_styling=force_styling)
    manp = charm / ".composer.manifest"
    comp = charm / "composer.yaml"
    if not manp.exists() or not comp.exists():
        return
    manifest = json.loads(manp.text())
    composer = yaml.load(comp.open())
    a, c, d = utils.delta_signatures(manp)

    # ordered list of layers used for legend
    layers = list(manifest['layers'])

    def get_depth(e):
        rel = e.relpath(charm)
        depth = len(rel.splitall()) - 2
        return rel, depth

    def get_suffix(rel):
        suffix = ""
        if rel in a:
            suffix = "+"
        elif rel in c:
            suffix = "*"
        return suffix

    def get_color(rel):
        # name of layer this belongs to
        color = tw.term.normal
        if rel in manifest['signatures']:
            layer = manifest['signatures'][rel][0]
            layer_key = layers.index(layer)
            color = getattr(tw, theme.get(layer_key, "normal"))
        else:
            if entry.isdir():
                color = tw.blue
        return color

    tw.write("Inspect %s\n" % composer["is"])
    for layer in layers:
        tw.write("# {color}{layer}{t.normal}\n",
                 color=getattr(tw, theme.get(layers.index(layer), "normal")),
                 layer=layer)
    tw.write("\n")
    tw.write("{t.blue}{target}{t.normal}\n", target=charm)

    ignorer = utils.ignore_matcher(config.DEFAULT_IGNORES)
    walk = sorted(utils.walk(charm, get_depth), key=lambda x: x[1][0])
    for i in range(len(walk) - 1):
        entry, (rel, depth) = walk[i]
        nEnt, (nrel, ndepth) = walk[i + 1]
        if not ignorer(rel):
            continue

        tw.write("{prefix}{layerColor}{entry} "
                 "{t.bold}{suffix}{t.normal}\n",
                 prefix=get_prefix(walk, i, depth, ndepth),
                 layerColor=get_color(rel),
                 suffix=get_suffix(rel),
                 entry=rel.name)
示例#3
0
 def exec_plan(self, plan=None, layers=None):
     signatures = {}
     cont = True
     for phase in self.PHASES:
         for tactic in plan:
             if phase == "lint":
                 cont &= tactic.lint()
                 if cont is False and self.force is not True:
                     return
             elif phase == "read":
                 # We use a read (into memory phase to make layer comps
                 # simpler)
                 tactic.read()
             elif phase == "call":
                 tactic()
             elif phase == "sign":
                 sig = tactic.sign()
                 if sig:
                     signatures.update(sig)
     new_repo = not self.manifest.exists()
     if new_repo:
         added, changed, removed = set(), set(), set()
     else:
         ignores = utils.ignore_matcher(DEFAULT_IGNORES)
         added, changed, _ = utils.delta_signatures(self.manifest, ignores)
         removed = self.clean_removed(signatures)
     # write out the sigs
     if "sign" in self.PHASES:
         self.write_signatures(signatures, layers)
     if self.report:
         self.write_report(new_repo, added, changed, removed)
示例#4
0
    def validate(self):
        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn(
                "Conflict: File in destination directory "
                "was added after charm build: %s", f)
        for f in c:
            log.warn(
                "Conflict: File in destination directory "
                "was modified after charm build: %s", f)
        for f in d:
            log.warn(
                "Conflict: File in destination directory "
                "was deleted after charm build: %s", f)
        if a or c or d:
            if self.force is True:
                log.info("Continuing with known changes to target layer. "
                         "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#5
0
 def exec_plan(self, plan=None, layers=None):
     signatures = {}
     cont = True
     for phase in self.PHASES:
         for tactic in plan:
             if phase == "lint":
                 cont &= tactic.lint()
                 if cont is False and self.force is not True:
                     # no message, reason will already have been logged
                     raise BuildError()
             elif phase == "read":
                 # We use a read (into memory phase to make layer comps
                 # simpler)
                 tactic.read()
             elif phase == "call":
                 tactic()
             elif phase == "sign":
                 sig = tactic.sign()
                 if sig:
                     signatures.update(sig)
     new_repo = not self.manifest.exists()
     if new_repo:
         added, changed, removed = set(), set(), set()
     else:
         added, changed, _ = utils.delta_signatures(self.manifest)
         removed = self.clean_removed(signatures)
     # write out the sigs
     if "sign" in self.PHASES:
         self.write_signatures(signatures, layers)
     if self.report:
         self.write_report(new_repo, added, changed, removed)
示例#6
0
 def exec_plan(self, plan=None, layers=None):
     signatures = {}
     cont = True
     for phase in self.PHASES:
         for tactic in plan:
             if phase == "lint":
                 cont &= tactic.lint()
                 if cont is False and self.force is not True:
                     # no message, reason will already have been logged
                     raise BuildError()
             elif phase == "read":
                 # We use a read (into memory phase to make layer comps
                 # simpler)
                 tactic.read()
             elif phase == "call":
                 tactic()
             elif phase == "sign":
                 sig = tactic.sign()
                 if sig:
                     signatures.update(sig)
     new_repo = not self.manifest.exists()
     if new_repo:
         added, changed, removed = set(), set(), set()
     else:
         added, changed, _ = utils.delta_signatures(self.manifest)
         removed = self.clean_removed(signatures)
     # write out the sigs
     if "sign" in self.PHASES:
         self.write_signatures(signatures, layers)
     if self.report:
         self.write_report(new_repo, added, changed, removed)
示例#7
0
 def exec_plan(self, plan=None, layers=None):
     signatures = {}
     cont = True
     for phase in self.PHASES:
         for tactic in plan:
             if phase == "lint":
                 cont &= tactic.lint()
                 if cont is False and self.force is not True:
                     return
             elif phase == "read":
                 # We use a read (into memory phase to make layer comps
                 # simpler)
                 tactic.read()
             elif phase == "call":
                 tactic()
             elif phase == "sign":
                 sig = tactic.sign()
                 if sig:
                     signatures.update(sig)
     new_repo = not self.manifest.exists()
     if new_repo:
         added, changed, removed = set(), set(), set()
     else:
         ignores = utils.ignore_matcher(DEFAULT_IGNORES)
         added, changed, _ = utils.delta_signatures(self.manifest, ignores)
         removed = self.clean_removed(signatures)
     # write out the sigs
     if "sign" in self.PHASES:
         self.write_signatures(signatures, layers)
     if self.report:
         self.write_report(new_repo, added, changed, removed)
示例#8
0
    def validate(self):
        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn(
                "Added unexpected file, should be in a base layer: %s", f)
        for f in c:
            log.warn(
                "Changed file owned by another layer: %s", f)
        for f in d:
            log.warn(
                "Deleted a file owned by another layer: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#9
0
    def validate(self):
        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn("Conflict: File in destination directory "
                     "was added after charm build: %s", f)
        for f in c:
            log.warn("Conflict: File in destination directory "
                     "was modified after charm build: %s", f)
        for f in d:
            log.warn("Conflict: File in destination directory "
                     "was deleted after charm build: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#10
0
    def validate(self):
        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn(
                "Added unexpected file, should be in a base layer: %s", f)
        for f in c:
            log.warn(
                "Changed file owned by another layer: %s", f)
        for f in d:
            log.warn(
                "Deleted a file owned by another layer: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#11
0
    def validate(self):
        p = self.target_dir / ".composer.manifest"
        if not p.exists():
            return [], [], []
        ignorer = utils.ignore_matcher(DEFAULT_IGNORES)
        a, c, d = utils.delta_signatures(p, ignorer)

        for f in a:
            log.warn(
                "Added unexpected file, should be in a base layer: %s", f)
        for f in c:
            log.warn(
                "Changed file owned by another layer: %s", f)
        for f in d:
            log.warn(
                "Deleted a file owned by another layer: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise ValueError(
                    "Unable to continue due to unexpected modifications (try --force)")
        return a, c, d
示例#12
0
    def validate(self):
        if not (self.name and str(self.name)[0] in string.ascii_lowercase):
            raise BuildError('Charm name must start with a lower-case letter')

        for cls in (InterfaceFetcher, LayerFetcher):
            if cls.OLD_ENVIRON in os.environ and cls.ENVIRON not in os.environ:
                log.warning('DEPRECATED: {} environment variable; '
                            'please use {} instead'.format(
                                cls.OLD_ENVIRON, cls.ENVIRON))

        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn(
                "Conflict: File in destination directory "
                "was added after charm build: %s", f)
        for f in c:
            log.warn(
                "Conflict: File in destination directory "
                "was modified after charm build: %s", f)
        for f in d:
            log.warn(
                "Conflict: File in destination directory "
                "was deleted after charm build: %s", f)
        if a or c or d:
            if self.force is True:
                log.info("Continuing with known changes to target layer. "
                         "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#13
0
    def validate(self):
        if not (self.name and str(self.name)[0] in string.ascii_lowercase):
            raise BuildError('Charm name must start with a lower-case letter')

        for cls in (InterfaceFetcher, LayerFetcher):
            if cls.OLD_ENVIRON in os.environ and cls.ENVIRON not in os.environ:
                log.warning('DEPRECATED: {} environment variable; '
                            'please use {} instead'.format(cls.OLD_ENVIRON,
                                                           cls.ENVIRON))

        self._validate_charm_repo()

        if not self.manifest.exists():
            return [], [], []
        a, c, d = utils.delta_signatures(self.manifest)

        for f in a:
            log.warn("Conflict: File in destination directory "
                     "was added after charm build: %s", f)
        for f in c:
            log.warn("Conflict: File in destination directory "
                     "was modified after charm build: %s", f)
        for f in d:
            log.warn("Conflict: File in destination directory "
                     "was deleted after charm build: %s", f)
        if a or c or d:
            if self.force is True:
                log.info(
                    "Continuing with known changes to target layer. "
                    "Changes will be overwritten")
            else:
                raise BuildError(
                    "Unable to continue due to unexpected modifications "
                    "(try --force)")

        return a, c, d
示例#14
0
def inspect(charm, force_styling=False, annotate=False):
    tw = utils.TermWriter(force_styling=force_styling)
    manp = charm / ".build.manifest"
    comp = charm / "layer.yaml"
    if not manp.exists() or not comp.exists():
        return
    manifest = json.loads(manp.text())
    composer = yaml.safe_load(comp.open())
    a, c, d = utils.delta_signatures(manp)

    # ordered list of layers used for legend
    if isinstance(manifest['layers'][0], dict):
        layers = [layer['url'] for layer in manifest['layers']]
    else:
        layers = list(manifest['layers'])
    layers.reverse()
    while layers[0].startswith('interface:'):
        layers.append(layers.pop(0))

    def get_depth(e):
        rel = e.relpath(charm)
        depth = len(rel.splitall()) - 2
        return rel, depth

    def get_suffix(rel):
        suffix = ""
        if rel in a:
            suffix = "+"
        elif rel in c:
            suffix = "*"
        return suffix

    def get_color(rel):
        # name of layer this belongs to
        color = tw.term.normal
        if rel in manifest['signatures']:
            layer = manifest['signatures'][rel][0]
            if layer in layers:
                layer_key = layers.index(layer)
            else:
                # handle special build created artifacts, which have
                # a "layer name" of "build" (mostly the manifest itself)
                layer_key = -1
            color = getattr(tw, theme.get(layer_key, "normal"))
        else:
            if entry.isdir():
                color = tw.blue
        return color

    tw.write("Inspect %s\n" % composer["is"])
    if tw.does_styling or force_styling:
        tw.write("\n")
        tw.write("Color key:\n")
        for i, layer in enumerate(layers):
            tw.write("# {color}{layer}{t.normal}\n",
                     color=getattr(tw, theme.get(i, "normal")),
                     layer=layer)
    else:
        # force annotations if we can't use color
        annotate = True
    tw.write("\n")
    tw.write("{t.blue}{target}{t.normal}\n", target=charm)

    ignorer = utils.ignore_matcher(config.DEFAULT_IGNORES)
    walk = sorted(utils.walk(charm, get_depth),
                  key=lambda x: x[1][0])
    for i in range(len(walk) - 1):
        entry, (rel, depth) = walk[i]
        nEnt, (nrel, ndepth) = walk[i + 1]
        if not ignorer(rel):
            continue

        if annotate and rel in manifest['signatures']:
            layer_name = manifest['signatures'][rel][0]
            if layer_name == 'build':
                # handle special build created artifacts, which have
                # a "layer name" of "build" (mostly the manifest itself)
                annotation = ' ({}build artifact{})'.format(tw.bright_black,
                                                            tw.normal)
            else:
                annotation = ' (from {}{}{})'.format(get_color(rel),
                                                     layer_name,
                                                     tw.normal)
        else:
            annotation = ''
        tw.write("{prefix}{layerColor}{entry} "
                 "{t.bold}{suffix}{t.normal}{annotation}\n",
                 prefix=get_prefix(walk, i, depth, ndepth),
                 layerColor=get_color(rel),
                 suffix=get_suffix(rel),
                 entry=rel.name,
                 annotation=annotation)
示例#15
0
def inspect(charm, force_styling=False):
    tw = utils.TermWriter(force_styling=force_styling)
    manp = charm / ".composer.manifest"
    comp = charm / "composer.yaml"
    if not manp.exists() or not comp.exists():
        return
    manifest = json.loads(manp.text())
    composer = yaml.load(comp.open())
    a, c, d = utils.delta_signatures(manp)

    # ordered list of layers used for legend
    layers = list(manifest['layers'])

    def get_depth(e):
        rel = e.relpath(charm)
        depth = len(rel.splitall()) - 2
        return rel, depth

    def get_suffix(rel):
        suffix = ""
        if rel in a:
            suffix = "+"
        elif rel in c:
            suffix = "*"
        return suffix

    def get_color(rel):
        # name of layer this belongs to
        color = tw.term.normal
        if rel in manifest['signatures']:
            layer = manifest['signatures'][rel][0]
            layer_key = layers.index(layer)
            color = getattr(tw, theme.get(layer_key, "normal"))
        else:
            if entry.isdir():
                color = tw.blue
        return color

    tw.write("Inspect %s\n" % composer["is"])
    for layer in layers:
        tw.write("# {color}{layer}{t.normal}\n",
                 color=getattr(tw, theme.get(
                     layers.index(layer), "normal")),
                 layer=layer)
    tw.write("\n")
    tw.write("{t.blue}{target}{t.normal}\n", target=charm)

    ignorer = utils.ignore_matcher(config.DEFAULT_IGNORES)
    walk = sorted(utils.walk(charm, get_depth),
                    key=lambda x: x[1][0])
    for i in range(len(walk) - 1):
        entry, (rel, depth) = walk[i]
        nEnt, (nrel, ndepth) = walk[i + 1]
        if not ignorer(rel):
            continue

        tw.write("{prefix}{layerColor}{entry} "
                    "{t.bold}{suffix}{t.normal}\n",
                    prefix=get_prefix(walk, i, depth, ndepth),
                    layerColor=get_color(rel),
                    suffix=get_suffix(rel),
                    entry=rel.name)
示例#16
0
def inspect(charm, force_styling=False, annotate=False):
    tw = utils.TermWriter(force_styling=force_styling)
    manp = charm / ".build.manifest"
    comp = charm / "layer.yaml"
    if not manp.exists() or not comp.exists():
        return
    manifest = json.loads(manp.text())
    composer = yaml.safe_load(comp.open())
    a, c, d = utils.delta_signatures(manp)

    # ordered list of layers used for legend
    if isinstance(manifest['layers'][0], dict):
        layers = [layer['url'] for layer in manifest['layers']]
    else:
        layers = list(manifest['layers'])
    layers.reverse()
    while layers[0].startswith('interface:'):
        layers.append(layers.pop(0))

    def get_depth(e):
        rel = e.relpath(charm)
        depth = len(rel.splitall()) - 2
        return rel, depth

    def get_suffix(rel):
        suffix = ""
        if rel in a:
            suffix = "+"
        elif rel in c:
            suffix = "*"
        return suffix

    def get_color(rel):
        # name of layer this belongs to
        color = tw.term.normal
        if rel in manifest['signatures']:
            layer = manifest['signatures'][rel][0]
            if layer in layers:
                layer_key = layers.index(layer)
            else:
                # handle special build created artifacts, which have
                # a "layer name" of "build" (mostly the manifest itself)
                layer_key = -1
            color = getattr(tw, theme.get(layer_key, "normal"))
        else:
            if entry.isdir():
                color = tw.blue
        return color

    tw.write("Inspect %s\n" % composer["is"])
    if tw.does_styling or force_styling:
        tw.write("\n")
        tw.write("Color key:\n")
        for i, layer in enumerate(layers):
            tw.write("# {color}{layer}{t.normal}\n",
                     color=getattr(tw, theme.get(i, "normal")),
                     layer=layer)
    else:
        # force annotations if we can't use color
        annotate = True
    tw.write("\n")
    tw.write("{t.blue}{target}{t.normal}\n", target=charm)

    ignorer = utils.ignore_matcher(config.DEFAULT_IGNORES)
    walk = sorted(utils.walk(charm, get_depth), key=lambda x: x[1][0])
    for i in range(len(walk) - 1):
        entry, (rel, depth) = walk[i]
        nEnt, (nrel, ndepth) = walk[i + 1]
        if not ignorer(rel):
            continue

        if annotate and rel in manifest['signatures']:
            layer_name = manifest['signatures'][rel][0]
            if layer_name == 'build':
                # handle special build created artifacts, which have
                # a "layer name" of "build" (mostly the manifest itself)
                annotation = ' ({}build artifact{})'.format(
                    tw.bright_black, tw.normal)
            else:
                annotation = ' (from {}{}{})'.format(get_color(rel),
                                                     layer_name, tw.normal)
        else:
            annotation = ''
        tw.write(
            "{prefix}{layerColor}{entry} "
            "{t.bold}{suffix}{t.normal}{annotation}\n",
            prefix=get_prefix(walk, i, depth, ndepth),
            layerColor=get_color(rel),
            suffix=get_suffix(rel),
            entry=rel.name,
            annotation=annotation)