Exemplo n.º 1
0
    def seperator(self) -> PathSeperators:
        """
        Get the seperator used to demarcate YAML Path segments.

        Parameters:  N/A

        Returns:  (PathSeperators) The segment demarcation symbol

        Raises:  N/A
        """
        if self._seperator is PathSeperators.AUTO:
            self._seperator = PathSeperators.infer_seperator(self._original)

        return self._seperator
Exemplo n.º 2
0
def processcli():
    """Process command-line arguments."""
    parser = argparse.ArgumentParser(
        description=(
            "Changes one or more Scalar values in a YAML/JSON/Compatible"
            " document at a specified YAML Path.  Matched values can be"
            " checked before they are replaced to mitigate accidental change."
            "  When matching singular results, the value can be archived to"
            " another key before it is replaced.  Further, EYAML can be"
            " employed to encrypt the new values and/or decrypt an old value"
            " before checking it."),
        epilog=(
            "When no changes are made, no backup is created, even when"
            " -b/--backup is specified.  For more information about YAML"
            " Paths, please visit https://github.com/wwkimball/yamlpath/wiki."
            "  To report issues with this tool or to request enhancements,"
            " please visit https://github.com/wwkimball/yamlpath/issues."))
    parser.add_argument("-V",
                        "--version",
                        action="version",
                        version="%(prog)s " + YAMLPATH_VERSION)

    required_group = parser.add_argument_group("required settings")
    required_group.add_argument(
        "-g",
        "--change",
        required=True,
        metavar="YAML_PATH",
        help="YAML Path where the target value is found")

    inputex_group = parser.add_argument_group("input options")
    input_group = inputex_group.add_mutually_exclusive_group()
    input_group.add_argument(
        "-a",
        "--value",
        help="set the new value from the command-line instead of STDIN")
    input_group.add_argument(
        "-A",
        "--aliasof",
        metavar="ANCHOR",
        help="set the value as a YAML Alias of an existing Anchor, by name "
        "(merely copies the target value for non-YAML files)")
    input_group.add_argument(
        "-f",
        "--file",
        help="read the new value from file (discarding any trailing\
              new-lines)")
    input_group.add_argument(
        "-i",
        "--stdin",
        action="store_true",
        help="accept the new value from STDIN (best for sensitive data)")
    input_group.add_argument(
        "-R",
        "--random",
        type=int,
        metavar="LENGTH",
        help="randomly generate a replacement value of a set length")
    input_group.add_argument("-N",
                             "--null",
                             action="store_true",
                             help="sets the value to null")
    input_group.add_argument(
        "-D",
        "--delete",
        action="store_true",
        help="delete rather than change target node(s); implies"
        " --mustexist|-m")

    parser.add_argument(
        "-F",
        "--format",
        default="default",
        choices=[l.lower() for l in YAMLValueFormats.get_names()],
        type=str.lower,
        help="override automatic formatting of the new value")
    parser.add_argument("-c",
                        "--check",
                        help="check the value before replacing it")
    parser.add_argument(
        "-s",
        "--saveto",
        metavar="YAML_PATH",
        help="save the old value to YAML_PATH before replacing it; implies\
              --mustexist")
    parser.add_argument(
        "-m",
        "--mustexist",
        action="store_true",
        help="require that the --change YAML_PATH already exist in YAML_FILE")
    parser.add_argument(
        "-b",
        "--backup",
        action="store_true",
        help="save a backup YAML_FILE with an extra .bak file-extension")
    parser.add_argument(
        "-t",
        "--pathsep",
        default="dot",
        choices=PathSeperators,
        metavar=PathSeperators.get_choices(),
        type=PathSeperators.from_str,
        help="indicate which YAML Path seperator to use when rendering\
              results; default=dot")

    parser.add_argument(
        "-M",
        "--random-from",
        metavar="CHARS",
        default=(string.ascii_uppercase + string.ascii_lowercase +
                 string.digits),
        help="characters from which to build a value for --random; default="
        "all upper- and lower-case letters and all digits")
    parser.add_argument(
        "-H",
        "--anchor",
        metavar="ANCHOR",
        help="when --aliasof|-A points to a value which is not already"
        " Anchored, a new Anchor with this name is created; renames an"
        " existing Anchor if already set")
    parser.add_argument(
        "-T",
        "--tag",
        metavar="TAG",
        help="assign a custom YAML (data-type) tag to the changed nodes; can"
        " be used without other input options to assign or change a tag")

    eyaml_group = parser.add_argument_group(
        "EYAML options", "Left unset, the EYAML keys will default to your\
         system or user defaults.  You do not need to supply a private key\
         unless you enable --check and the old value is encrypted.")
    eyaml_group.add_argument("-e",
                             "--eyamlcrypt",
                             action="store_true",
                             help="encrypt the new value using EYAML")
    eyaml_group.add_argument(
        "-x",
        "--eyaml",
        default="eyaml",
        help="the eyaml binary to use when it isn't on the PATH")
    eyaml_group.add_argument("-r", "--privatekey", help="EYAML private key")
    eyaml_group.add_argument("-u", "--publickey", help="EYAML public key")

    parser.add_argument(
        "-S",
        "--nostdin",
        action="store_true",
        help=("Do not implicitly read from STDIN, even when there is no"
              " YAML_FILE with a non-TTY session"))

    noise_group = parser.add_mutually_exclusive_group()
    noise_group.add_argument("-d",
                             "--debug",
                             action="store_true",
                             help="output debugging details")
    noise_group.add_argument("-v",
                             "--verbose",
                             action="store_true",
                             help="increase output verbosity")
    noise_group.add_argument("-q",
                             "--quiet",
                             action="store_true",
                             help="suppress all output except errors")

    parser.add_argument(
        "yaml_file",
        metavar="YAML_FILE",
        nargs="?",
        help="the YAML file to update; omit or use - to read from STDIN")
    return parser.parse_args()
Exemplo n.º 3
0
def processcli():
    """Process command-line arguments."""
    search_ops = ", ".join(PathSearchMethods.get_operators()) + ", or !"
    parser = argparse.ArgumentParser(
        description=(
            "Returns zero or more YAML Paths indicating where in given"
            " YAML/JSON/Compatible data one or more search expressions match."
            "  Values, keys, and/or anchors can be searched.  EYAML can be"
            " employed to search encrypted values."),
        epilog=(
            "A search or exception EXPRESSION takes the form of a YAML Path"
            " search operator -- {} -- followed by the search term, omitting"
            " the left-hand operand.  For more information about YAML Paths,"
            " please visit https://github.com/wwkimball/yamlpath/wiki.  To"
            " report issues with this tool or to request enhancements, please"
            " visit https://github.com/wwkimball/yamlpath/issues.")
            .format(search_ops)
    )
    parser.add_argument("-V", "--version", action="version",
                        version="%(prog)s " + YAMLPATH_VERSION)

    required_group = parser.add_argument_group("required settings")
    required_group.add_argument(
        "-s", "--search",
        required=True,
        metavar="EXPRESSION", action="append",
        help="the search expression; can be set more than once")

    parser.add_argument(
        "-c", "--except",
        metavar="EXPRESSION", action="append", dest="except_expression",
        help="except results matching this search expression; can be set more\
            than once")

    parser.add_argument(
        "-m", "--expand",
        action="store_true",
        help="expand matching parent nodes to list all permissible child leaf\
              nodes (see \"reference handling options\" for restrictions)")

    valdump_group = parser.add_argument_group("result printing options")
    valdump_group.add_argument(
        "-L", "--values",
        action="store_true",
        help="print the values or elements along with each YAML Path (complex\
            results are emitted as JSON; use --expand to emit only simple\
            values)")
    valdump_group.add_argument(
        "-F", "--nofile",
        action="store_true",
        help="omit source file path and name decorators from the output\
            (applies only when searching multiple files)")
    valdump_group.add_argument(
        "-X", "--noexpression",
        action="store_true",
        help="omit search expression decorators from the output")
    valdump_group.add_argument(
        "-P", "--noyamlpath",
        action="store_true",
        help="omit YAML Paths from the output (useful with --values or to\
            indicate whether a file has any matches without printing them\
            all, perhaps especially with --noexpression)")

    parser.add_argument(
        "-t", "--pathsep",
        default="dot",
        choices=PathSeperators,
        metavar=PathSeperators.get_choices(),
        type=PathSeperators.from_str,
        help="indicate which YAML Path seperator to use when rendering\
              results; default=dot")

    keyname_group_ex = parser.add_argument_group("key name searching options")
    keyname_group = keyname_group_ex.add_mutually_exclusive_group()
    keyname_group.add_argument(
        "-i", "--ignorekeynames",
        action="store_true",
        help="(default) do not search key names")
    keyname_group.add_argument(
        "-k", "--keynames",
        action="store_true",
        help="search key names in addition to values and array elements")
    keyname_group.add_argument(
        "-K", "--onlykeynames",
        action="store_true",
        help="only search key names (ignore all values and array elements)")

    parser.add_argument(
        "-a", "--refnames",
        action="store_true",
        help="also search the names of &anchor and *alias references")

    dedup_group_ex = parser.add_argument_group(
        "reference handling options",
        "Indicate how to treat anchor and alias references.  An anchor is an\
         original, reusable key or value.  All aliases become replaced by the\
         anchors they reference when YAML data is read.  These options specify\
         how to handle this duplication of keys and values.  Note that the\
         default behavior includes all aliased keys but not aliased values.")
    dedup_group = dedup_group_ex.add_mutually_exclusive_group()
    dedup_group.add_argument(
        "-A", "--anchorsonly",
        action="store_const",
        dest="include_aliases",
        const=IncludeAliases.ANCHORS_ONLY,
        help="include only original matching key and value anchors in results,\
              discarding all aliased keys and values (including child nodes)")
    dedup_group.add_argument(
        "-Y", "--allowkeyaliases",
        action="store_const",
        dest="include_aliases",
        const=IncludeAliases.INCLUDE_KEY_ALIASES,
        help="(default) include matching key aliases, permitting search\
              traversal into their child nodes")
    dedup_group.add_argument(
        "-y", "--allowvaluealiases",
        action="store_const",
        dest="include_aliases",
        const=IncludeAliases.INCLUDE_VALUE_ALIASES,
        help="include matching value aliases (does not permit search traversal\
              into aliased keys)")
    dedup_group.add_argument(
        "-l", "--allowaliases",
        action="store_const",
        dest="include_aliases",
        const=IncludeAliases.INCLUDE_ALL_ALIASES,
        help="include all matching key and value aliases")

    eyaml_group = parser.add_argument_group(
        "EYAML options", "Left unset, the EYAML keys will default to your\
         system or user defaults.  Both keys must be set either here or in\
         your system or user EYAML configuration file when using EYAML.")
    eyaml_group.add_argument(
        "-e", "--decrypt",
        action="store_true",
        help="decrypt EYAML values in order to search them (otherwise, search\
            the encrypted blob)"
    )
    eyaml_group.add_argument(
        "-x", "--eyaml",
        default="eyaml",
        help="the eyaml binary to use when it isn't on the PATH")
    eyaml_group.add_argument("-r", "--privatekey", help="EYAML private key")
    eyaml_group.add_argument("-u", "--publickey", help="EYAML public key")

    parser.add_argument(
        "-S", "--nostdin", action="store_true",
        help=(
            "Do not implicitly read from STDIN, even when there are\n"
            "no - pseudo-files in YAML_FILEs with a non-TTY session"))

    noise_group = parser.add_mutually_exclusive_group()
    noise_group.add_argument(
        "-d", "--debug",
        action="store_true",
        help="output debugging details")
    noise_group.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="increase output verbosity")
    noise_group.add_argument(
        "-q", "--quiet",
        action="store_true",
        help="suppress all non-result output except errors")

    parser.add_argument("yaml_files", metavar="YAML_FILE", nargs="*",
                        help="one or more YAML files to search; omit or use -"
                        " to read from STDIN")

    parser.set_defaults(include_aliases=IncludeAliases.INCLUDE_KEY_ALIASES)

    return parser.parse_args()
Exemplo n.º 4
0
def processcli():
    """Process command-line arguments."""
    parser = argparse.ArgumentParser(
        description="Changes one or more values in a YAML file at a specified\
            YAML Path.  Matched values can be checked before they are replaced\
            to mitigate accidental change. When matching singular results, the\
            value can be archived to another key before it is replaced.\
            Further, EYAML can be employed to encrypt the new values and/or\
            decrypt an old value before checking them.",
        epilog="When no changes are made, no backup is created, even when\
            -b/--backup is specified.  For more information about YAML Paths,\
            please visit https://github.com/wwkimball/yamlpath.")
    parser.add_argument("-V",
                        "--version",
                        action="version",
                        version="%(prog)s " + MY_VERSION)

    required_group = parser.add_argument_group("required settings")
    required_group.add_argument(
        "-g",
        "--change",
        required=True,
        metavar="YAML_PATH",
        help="YAML Path where the target value is found")

    inputex_group = parser.add_argument_group("input options")
    input_group = inputex_group.add_mutually_exclusive_group()
    input_group.add_argument(
        "-a",
        "--value",
        help="set the new value from the command-line instead of STDIN")
    input_group.add_argument(
        "-f",
        "--file",
        help="read the new value from file (discarding any trailing\
              new-lines)")
    input_group.add_argument(
        "-i",
        "--stdin",
        action="store_true",
        help="accept the new value from STDIN (best for sensitive data)")
    input_group.add_argument(
        "-R",
        "--random",
        type=int,
        metavar="LENGTH",
        help="randomly generate a replacement value of a set length")

    parser.add_argument(
        "-F",
        "--format",
        default="default",
        choices=[l.lower() for l in YAMLValueFormats.get_names()],
        type=str.lower,
        help="override automatic formatting of the new value")
    parser.add_argument("-c",
                        "--check",
                        help="check the value before replacing it")
    parser.add_argument(
        "-s",
        "--saveto",
        metavar="YAML_PATH",
        help="save the old value to YAML_PATH before replacing it; implies\
              --mustexist")
    parser.add_argument(
        "-m",
        "--mustexist",
        action="store_true",
        help="require that the --change YAML_PATH already exist in YAML_FILE")
    parser.add_argument(
        "-b",
        "--backup",
        action="store_true",
        help="save a backup YAML_FILE with an extra .bak file-extension")
    parser.add_argument(
        "-t",
        "--pathsep",
        default="dot",
        choices=PathSeperators,
        metavar=PathSeperators.get_choices(),
        type=PathSeperators.from_str,
        help="indicate which YAML Path seperator to use when rendering\
              results; default=dot")

    eyaml_group = parser.add_argument_group(
        "EYAML options", "Left unset, the EYAML keys will default to your\
         system or user defaults.  You do not need to supply a private key\
         unless you enable --check and the old value is encrypted.")
    eyaml_group.add_argument("-e",
                             "--eyamlcrypt",
                             action="store_true",
                             help="encrypt the new value using EYAML")
    eyaml_group.add_argument(
        "-x",
        "--eyaml",
        default="eyaml",
        help="the eyaml binary to use when it isn't on the PATH")
    eyaml_group.add_argument("-r", "--privatekey", help="EYAML private key")
    eyaml_group.add_argument("-u", "--publickey", help="EYAML public key")

    noise_group = parser.add_mutually_exclusive_group()
    noise_group.add_argument("-d",
                             "--debug",
                             action="store_true",
                             help="output debugging details")
    noise_group.add_argument("-v",
                             "--verbose",
                             action="store_true",
                             help="increase output verbosity")
    noise_group.add_argument("-q",
                             "--quiet",
                             action="store_true",
                             help="suppress all output except errors")

    parser.add_argument("yaml_file",
                        metavar="YAML_FILE",
                        help="the YAML file to update")
    return parser.parse_args()
Exemplo n.º 5
0
def processcli():
    """Process command-line arguments."""
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter,
        description=(
            "Compare YAML/JSON/Compatible documents node by node.  EYAML can"
            " be employed to\ncompare encrypted values."),
        epilog="""
configuration file:
  The CONFIG file is an INI file with up to three sections:
  [defaults] Sets equivalents of --arrays|-A and --aoh|-O.
  [rules]    Each entry is a YAML Path assigning --arrays|-A or --aoh|-O for
             precise nodes.
  [keys]     Wherever --aoh=key (or -O key) or --aoh=deep (or -O deep), each
             entry is treated as a record with an identity key.  In order to
             match RHS records to LHS records, a key must be known and is
             identified on a YAML Path basis via this section.  Where not
             specified, the first attribute of the first record in the
             Array-of-Hashes is presumed the identity key for all records in
             the set.

input files:
  Only one input file may be the - pseudo-file (read from STDIN).  Because the
  relative position of the two input files is important, this will not be
  inferred; you must use - to indicate which document is read from STDIN.

  It doesn't make any sense to compare multi-document files, so only single-
  document files are supported.

For more information about YAML Paths, please visit
https://github.com/wwkimball/yamlpath/wiki.

To report issues with this tool or to request enhancements, please visit
https://github.com/wwkimball/yamlpath/issues.
""")
    parser.add_argument("-V",
                        "--version",
                        action="version",
                        version="%(prog)s " + YAMLPATH_VERSION)

    parser.add_argument(
        "-c",
        "--config",
        help="INI syle configuration file for YAML Path specified\ncomparison"
        " control options")

    parser.add_argument(
        "-A",
        "--arrays",
        choices=[l.lower() for l in ArrayDiffOpts.get_names()],
        type=str.lower,
        help="default means by which Arrays are compared (overrides\n"
        "[defaults]arrays but is overridden on a YAML Path\nbasis via"
        " --config|-c); default={}".format(ArrayDiffOpts.POSITION))
    parser.add_argument(
        "-O",
        "--aoh",
        choices=[l.lower() for l in AoHDiffOpts.get_names()],
        type=str.lower,
        help=(
            "default means by which Arrays-of-Hashes are compared\n(overrides"
            " [defaults]aoh but is overridden on a YAML\nPath basis in [rules]"
            " set via --config|-c);\ndefault={}".format(AoHDiffOpts.POSITION)))

    sameness_group = parser.add_mutually_exclusive_group()
    sameness_group.add_argument(
        "-s",
        "--same",
        action="store_true",
        help="Show all nodes which are the same in addition to\ndifferences")
    sameness_group.add_argument(
        "-o",
        "--onlysame",
        action="store_true",
        help="Show only nodes which are the same, still reporting\nthat"
        " differences exist -- when they do -- with an\nexit-state of 1")

    multi_doc_group = parser.add_argument_group(
        "multi-document source options",
        "As diffs can be performed only between two documents, one must be\n"
        "selected from multi-document sources when present.  Make a\n"
        "selection by indicating the zero-based index of the one document\n"
        "to use from each multi-document source (the first document is\n"
        "index 0).")
    multi_doc_group.add_argument(
        "-L",
        "--left-document-index",
        metavar="DOCUMENT_INDEX",
        type=int,
        help="zero-based document index of the LHS multi-document source")
    multi_doc_group.add_argument(
        "-R",
        "--right-document-index",
        metavar="DOCUMENT_INDEX",
        type=int,
        help="zero-based document index of the RHS multi-document source")

    parser.add_argument(
        "-t",
        "--pathsep",
        default="dot",
        choices=PathSeperators,
        metavar=PathSeperators.get_choices(),
        type=PathSeperators.from_str,
        help="indicate which YAML Path seperator to use when\nrendering"
        " results; default=dot")

    eyaml_group = parser.add_argument_group(
        "EYAML options", "Left unset, the EYAML keys will default to your"
        "system or user defaults.\nBoth keys must be set either here or in"
        "your system or user EYAML\nconfiguration file when using EYAML.")
    eyaml_group.add_argument(
        "-x",
        "--eyaml",
        default="eyaml",
        help="the eyaml binary to use when it isn't on the PATH")
    eyaml_group.add_argument("-r", "--privatekey", help="EYAML private key")
    eyaml_group.add_argument("-u", "--publickey", help="EYAML public key")
    eyaml_group.add_argument(
        "-E",
        "--ignore-eyaml-values",
        action="store_true",
        help="Do not use EYAML to compare encrypted data; rather,\ntreat"
        " ENC[...] values as regular strings")

    noise_group = parser.add_mutually_exclusive_group()
    noise_group.add_argument("-d",
                             "--debug",
                             action="store_true",
                             help="output debugging details")
    noise_group.add_argument("-v",
                             "--verbose",
                             action="store_true",
                             help="increase output verbosity")
    noise_group.add_argument("-q",
                             "--quiet",
                             action="store_true",
                             help="suppress all output except system errors")

    parser.add_argument("yaml_files",
                        metavar="YAML_FILE",
                        nargs=2,
                        help="exactly two YAML/JSON/compatible files to"
                        " compare; use\n- to read one document from"
                        " STDIN")

    return parser.parse_args()
 def test_get_names(self):
     assert PathSeperators.get_names() == [
         "AUTO",
         "DOT",
         "FSLASH",
     ]
 def test_infer_seperator(self, input, output):
     assert output == PathSeperators.infer_seperator(input)
 def test_from_str_nameerror(self):
     with pytest.raises(NameError):
         PathSeperators.from_str("NO SUCH NAME")
 def test_from_str(self, input, output):
     assert output == PathSeperators.from_str(input)
Exemplo n.º 10
0
def processcli():
    """Process command-line arguments."""
    parser = argparse.ArgumentParser(
        description=(
            "Retrieves one or more values from a YAML/JSON/Compatible"
            " file at a specified YAML Path.  Output is printed to STDOUT, one"
            " line per result.  When a result is a complex data-type (Array or"
            " Hash), a JSON dump is produced to represent it.  EYAML can be"
            " employed to decrypt the values."),
        epilog=(
            "For more information about YAML Paths, please visit"
            " https://github.com/wwkimball/yamlpath/wiki.  To report issues"
            " with this tool or to request enhancements, please visit"
            " https://github.com/wwkimball/yamlpath/issues."))
    parser.add_argument("-V",
                        "--version",
                        action="version",
                        version="%(prog)s " + YAMLPATH_VERSION)

    required_group = parser.add_argument_group("required settings")
    required_group.add_argument("-p",
                                "--query",
                                required=True,
                                metavar="YAML_PATH",
                                help="YAML Path to query")

    parser.add_argument(
        "-t",
        "--pathsep",
        default="dot",
        choices=PathSeperators,
        metavar=PathSeperators.get_choices(),
        type=PathSeperators.from_str,
        help="indicate which YAML Path seperator to use when rendering\
              results; default=dot")

    parser.add_argument(
        "-S",
        "--nostdin",
        action="store_true",
        help=(
            "Do not implicitly read from STDIN, even when YAML_FILE is not set"
            " and the session is non-TTY"))

    eyaml_group = parser.add_argument_group(
        "EYAML options", "Left unset, the EYAML keys will default to your\
         system or user defaults.  Both keys must be set either here or in\
         your system or user EYAML configuration file when using EYAML.")
    eyaml_group.add_argument(
        "-x",
        "--eyaml",
        default="eyaml",
        help="the eyaml binary to use when it isn't on the PATH")
    eyaml_group.add_argument("-r", "--privatekey", help="EYAML private key")
    eyaml_group.add_argument("-u", "--publickey", help="EYAML public key")

    noise_group = parser.add_mutually_exclusive_group()
    noise_group.add_argument("-d",
                             "--debug",
                             action="store_true",
                             help="output debugging details")
    noise_group.add_argument("-v",
                             "--verbose",
                             action="store_true",
                             help="increase output verbosity")
    noise_group.add_argument("-q",
                             "--quiet",
                             action="store_true",
                             help="suppress all output except errors")

    parser.add_argument(
        "yaml_file",
        metavar="YAML_FILE",
        nargs="?",
        help="the YAML file to query; omit or use - to read from STDIN")

    return parser.parse_args()