Esempio n. 1
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred.")

    parser.add_argument(
        "-l",
        "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to ./build/xeplist.xml)")

    parser.add_argument(
        "-v",
        "--verbose",
        help="Print additional metadata for deferred XEPs",
        action="store_true",
        default=False,
    )

    parser.add_argument(
        "-m",
        "--modify",
        default=False,
        metavar="INITIALS",
        help="Modify the to-be-deferred XEPs in-place and use the given "
        "INITIALS in the remarks.")

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("./build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)
    deferred = list(get_deferred(accepted))

    for deferred_info in deferred:
        if args.modify:
            defer_xep(deferred_info["number"],
                      deferred_info["last_revision"]["version"], args.modify)

        if args.verbose:
            print("XEP-{info[number]:04d}: {info[title]} "
                  "(last update {info[last_revision][date]:%Y-%m-%d})".format(
                      info=deferred_info))
        else:
            print(deferred_info["number"])
Esempio n. 2
0
def main():
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "-l", "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to ./build/xeplist.xml)"
    )

    parser.add_argument(
        "-d", "--dialect",
        default="unix",
    )

    parser.add_argument(
        "outfile",
    )

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("./build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)

    with open(args.outfile, "w") as f:
        writer = csv.writer(f, args.dialect)
        for number, info in sorted(accepted.items()):
            writer.writerow([
                number,
                info["title"],
                info["status"].value,
                info["last_revision"]["date"].date(),
                info["last_revision"]["version"],
            ])
Esempio n. 3
0
def main():
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "-l",
        "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to ./build/xeplist.xml)")

    parser.add_argument(
        "-d",
        "--dialect",
        default="unix",
    )

    parser.add_argument("outfile", )

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("./build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)

    with open(args.outfile, "w") as f:
        writer = csv.writer(f, args.dialect)
        for number, info in sorted(accepted.items()):
            writer.writerow([
                number,
                info["title"],
                info["status"].value,
                info["last_revision"]["date"].date(),
                info["last_revision"]["version"],
            ])
Esempio n. 4
0
File: makeent.py Progetto: Zash/xeps
def main():
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-l", "--xeplist",
        type=argparse.FileType("r"),
        default=None,
    )
    parser.add_argument(
        "xeps",
        metavar="NUM",
        type=int,
        nargs="+",
    )

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("build/xeplist.xml", "r")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)

    for num in args.xeps:
        info = accepted[num]
        print(
            """<!ENTITY xep{number:04d} "<span class='ref'>"""
            """<link url='{url}'>{title} (XEP-{number:04d})</link></span> """
            """<note>XEP-{number:04d}: {title} &lt;<link url='{url}'>"""
            """{url}</link>&gt;.</note>" >""".format(
                title=html.escape(info["title"]),
                number=num,
                url="https://xmpp.org/extensions/xep-{:04d}.html".format(
                    num,
                )
            )
        )
Esempio n. 5
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description=wraptext(DESCRIPTION),
        epilog=wraptext(EPILOG),
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "-c", "--config",
        metavar="FILE",
        type=argparse.FileType("r"),
        help="Configuration file",
    )
    parser.add_argument(
        "-y",
        dest="ask_confirmation",
        default=True,
        action="store_false",
        help="'I trust this script to do the right thing and send emails"
        "without asking for confirmation.'"
    )
    parser.add_argument(
        "--no-proto",
        dest="include_protoxep",
        default=True,
        action="store_false",
        help="Do not announce ProtoXEPs",
    )
    parser.add_argument(
        "-n", "--dry-run",
        dest="dry_run",
        action="store_true",
        default=False,
        help="Instead of sending emails, print them to stdout (implies -y)",
    )
    parser.add_argument(
        "--no-editorial",
        action="store_false",
        default=True,
        dest="include_editorial",
        help="Do not announce editorial changes."
    )
    parser.add_argument(
        "--no-non-editorial",
        action="store_false",
        default=True,
        dest="include_non_editorial",
        help="Do not announce non-editorial changes."
    )

    parser.add_argument(
        "old",
        type=argparse.FileType("rb"),
        help="Old xep-infos XML file",
    )
    parser.add_argument(
        "new",
        type=argparse.FileType("rb"),
        help="New xep-infos XML file",
    )

    parser.add_argument(
        "to",
        nargs="+",
        help="The mail addresses to send the update mails to."
    )

    args = parser.parse_args()

    can_be_interactive = (
        os.isatty(sys.stdin.fileno()) and
        os.isatty(sys.stdout.fileno())
    )

    if args.dry_run:
        args.ask_confirmation = False

    if args.ask_confirmation and not can_be_interactive:
        print("Cannot ask for confirmation (stdio is not a TTY), but -y is",
              "not given either. Aborting.", sep="\n", file=sys.stderr)
        sys.exit(2)

    config = configparser.ConfigParser()
    if args.config is not None:
        config.read_file(args.config)

    with args.old as f:
        tree = etree.parse(f)
    old_accepted, old_proto = load_xepinfos(tree)

    with args.new as f:
        tree = etree.parse(f)
    new_accepted, new_proto = load_xepinfos(tree)

    old_xeps = set(old_accepted.keys())
    new_xeps = set(new_accepted.keys())

    common_xeps = old_xeps & new_xeps
    added_xeps = new_xeps - old_xeps

    added_protos = set(new_proto.keys()) - set(old_proto.keys())

    updates = []

    for common_xep in common_xeps:
        old_info = old_accepted[common_xep]
        new_info = new_accepted[common_xep]

        action = diff_infos(old_info, new_info)
        if action == Action.UPDATE and not filter_bump_level(
                extract_version(old_info),
                extract_version(new_info),
                args.include_editorial,
                args.include_non_editorial):
            continue

        if action is not None:
            updates.append((common_xep, action, new_info))

    for added_xep in added_xeps:
        old_info = dummy_info(added_xep)
        new_info = new_accepted[added_xep]

        action = diff_infos(old_info, new_info)
        if action is not None:
            updates.append((added_xep, action, new_info))

    if args.include_protoxep:
        for added_proto in added_protos:
            old_info = dummy_info('xxxx')
            new_info = new_proto[added_proto]

            action = diff_infos(old_info, new_info)
            if action is not None:
                updates.append((added_proto, action, new_info))

    if args.dry_run:
        smtpconn = make_fake_smtpconn()
    else:
        if can_be_interactive:
            interactively_extend_smtp_config(config)

        try:
            smtpconn = make_smtpconn(config)
        except (configparser.NoSectionError,
                configparser.NoOptionError) as exc:
            print("Missing configuration: {}".format(exc),
                  file=sys.stderr)
            print("(cannot ask for configuration on stdio because it is "
                  "not a TTY)", file=sys.stderr)
            sys.exit(3)

    try:
        for id_, action, info in updates:
            if action == Action.PROTO:
                mail = make_proto_mail(info)
            else:
                mail = make_nonproto_mail(action, info)
            mail["Date"] = datetime.utcnow()
            mail["From"] = config.get("smtp", "from")
            mail["To"] = args.to

            if args.ask_confirmation:
                print()
                print("---8<---")
                print(mail.as_string())
                print("--->8---")
                print()
                choice = choose(
                    "Send this email? [y]es, [n]o, [a]bort: ",
                    "yna",
                    eof="a",
                )

                if choice == "n":
                    continue
                elif choice == "a":
                    print("Exiting on user request.", file=sys.stderr)
                    sys.exit(4)

            smtpconn.send_message(mail)
    finally:
        smtpconn.close()
Esempio n. 6
0
def main():
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "-c", "--config",
        metavar="FILE",
        type=argparse.FileType("r"),
        help="Configuration file",
    )
    parser.add_argument(
        "-y",
        dest="ask_confirmation",
        default=True,
        action="store_false",
        help="'I trust this script to do the right thing and send emails"
        "without asking for confirmation.'"
    )
    parser.add_argument(
        "-n", "--dry-run",
        dest="dry_run",
        action="store_true",
        default=False,
        help="Instead of sending emails, print them to stdout (implies -y)",
    )

    parser.add_argument(
        "--duration", "-d",
        metavar="DAYS",
        default=14,
        help="Duration of the CFE in days (default and at least: 14)",
        type=int,
    )

    parser.add_argument(
        "--xeplist",
        default=None,
        type=argparse.FileType("r")
    )

    parser.add_argument(
        "-x", "--xep",
        type=int,
        dest="xeps",
        action="append",
        default=[],
        help="XEP(s) to issue a CFE for"
    )

    parser.add_argument(
        "to",
        nargs="+",
        help="The mail addresses to send the update mails to."
    )

    args = parser.parse_args()

    can_be_interactive = (
        os.isatty(sys.stdin.fileno()) and
        os.isatty(sys.stdout.fileno())
    )

    if not args.xeps:
        print("nothing to do (use -x/--xep)", file=sys.stderr)
        sys.exit(1)

    if args.duration < 14:
        print("duration must be at least 14", file=sys.stderr)
        sys.exit(1)

    enddate = (datetime.utcnow() + timedelta(days=args.duration)).date()

    if args.dry_run:
        args.ask_confirmation = False

    if args.ask_confirmation and not can_be_interactive:
        print("Cannot ask for confirmation (stdio is not a TTY), but -y is",
              "not given either. Aborting.", sep="\n", file=sys.stderr)
        sys.exit(2)

    config = configparser.ConfigParser()
    if args.config is not None:
        config.read_file(args.config)

    if args.xeplist is None:
        args.xeplist = open("build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)
    accepted, _ = load_xepinfos(tree)

    matched_xeps = []
    has_error = False
    for num in args.xeps:
        try:
            info = accepted[num]
        except KeyError:
            print("no such xep: {}".format(num), file=sys.stderr)
            has_error = True
            continue

        if info["status"] != Status.DRAFT:
            print("XEP-{:04d} is in {}, but must be Draft".format(
                num,
                info["status"].value,
            ))
            has_error = True
            continue

        matched_xeps.append(info)

    if has_error:
        sys.exit(1)

    if args.dry_run:
        smtpconn = make_fake_smtpconn()
    else:
        if can_be_interactive:
            interactively_extend_smtp_config(config)

        try:
            smtpconn = make_smtpconn(config)
        except (configparser.NoSectionError,
                configparser.NoOptionError) as exc:
            print("Missing configuration: {}".format(exc),
                  file=sys.stderr)
            print("(cannot ask for configuration on stdio because it is "
                  "not a TTY)", file=sys.stderr)
            sys.exit(3)

    try:
        for info in matched_xeps:
            mail = make_mail(info, enddate)
            mail["Date"] = datetime.utcnow()
            mail["From"] = config.get("smtp", "from")
            mail["To"] = args.to

            if args.ask_confirmation:
                print()
                print("---8<---")
                print(mail.as_string())
                print("--->8---")
                print()
                choice = choose(
                    "Send this email? [y]es, [n]o, [a]bort: ",
                    "yna",
                    eof="a",
                )

                if choice == "n":
                    continue
                elif choice == "a":
                    print("Exiting on user request.", file=sys.stderr)
                    sys.exit(4)

            smtpconn.send_message(mail)
    finally:
        smtpconn.close()
Esempio n. 7
0
File: accept.py Progetto: Zash/xeps
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Accept an inbox XEP."
    )

    parser.add_argument(
        "-l", "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to {})".format(DEFAULT_XEPLIST_PATH)
    )

    parser.add_argument(
        "-y", "--yes",
        dest="ask",
        action="store_false",
        help="Assume default answer to all questions.",
        default=True,
    )

    parser.add_argument(
        "-f", "--force",
        dest="force",
        action="store_true",
        default=False,
        help="Force acceptance even if suspicious.",
    )

    parser.add_argument(
        "-c", "--commit",
        default=False,
        action="store_true",
        help="Make a git commit",
    )

    parser.add_argument(
        "item",
        help="Inbox name"
    )

    parser.add_argument(
        "votedate",
        type=isodate,
        help="The date of the vote, in ISO format (%%Y-%%m-%%d)."
    )

    parser.add_argument(
        "initials",
        help="Your editor initials"
    )

    args = parser.parse_args()

    if args.item.endswith(".xml"):
        # strip the path
        p = pathlib.Path(args.item)
        args.item = p.parts[-1].rsplit(".")[0]

    if args.xeplist is None:
        args.xeplist = open(DEFAULT_XEPLIST_PATH, "rb")

    if args.xeplist is not None:
        with args.xeplist as f:
            tree = etree.parse(f)
        accepted, inbox = load_xepinfos(tree)

    try:
        xepinfo = inbox[args.item]
    except KeyError:
        print("no such inbox xep: {!r}".format(args.item), file=sys.stderr)
        print("maybe run make build/xeplist.xml first?", file=sys.stderr)
        sys.exit(1)

    new_number = get_next_xep_number(accepted)

    new_filename = pathlib.Path(".") / "xep-{:04d}.xml".format(new_number)
    inbox_path = pathlib.Path("inbox") / "{}.xml".format(args.item)
    if new_filename.exists():
        raise FileExistsError(
            "Internal error: XEP file does already exist! ({})".format(
                new_filename
            )
        )
    if not inbox_path.exists():
        print("inbox file does not exist or is not readable: {}".format(
            inbox_path
        ))

    if args.ask:
        print("I am going to accept:")
        print()
        print("  Title: {!r}".format(xepinfo["title"]))
        print("  Abstract: {!r}".format(xepinfo["abstract"]))
        print("  Last Revision: {} ({})".format(
            xepinfo["last_revision"]["date"].date(),
            xepinfo["last_revision"]["version"],
        ))
        print()
        print("as new XEP-{:04d}.".format(new_number))
        print()
        choice = choose("Is this correct? [y]es, [n]o: ", "yn", eof="n")
        if choice != "y":
            print("aborted at user request")
            sys.exit(2)

    shutil.copy(str(inbox_path), str(new_filename))

    accept_xep(new_number,
               xepinfo["last_revision"]["version"],
               args.initials,
               xepinfo["approver"],
               args.votedate.date())

    if args.commit:
        subprocess.check_call([
            "git", "reset", "HEAD", ".",
        ])
        subprocess.check_call([
            "git", "add", new_filename.parts[-1],
        ])
        if args.ask:
            flags = ["-ve"]
        else:
            flags = []
        subprocess.check_call(
            [
                "git", "commit", "-m", "Accept {} as XEP-{:04}".format(
                    inbox_path,
                    new_number,
                )
            ] + flags
        )
Esempio n. 8
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred.")

    parser.add_argument("old",
                        type=argparse.FileType("rb"),
                        help="Old XEP list")

    parser.add_argument("new",
                        type=argparse.FileType("rb"),
                        help="New XEP list")

    parser.add_argument("-d",
                        "--xeps-dir",
                        type=pathlib.Path,
                        default=pathlib.Path.cwd() / "build",
                        help="Path to the built XEPs (defaults to ./build)")

    parser.add_argument(
        "-a",
        "--attic",
        type=pathlib.Path,
        default=pathlib.Path.cwd() / '../xep-attic/content/',
        help="Path to the attic (defaults to ../xep-attic/content/)")

    parser.add_argument(
        "xeps",
        nargs="*",
        type=int,
        help="Additional XEPs (by their number) to archive. Useful for "
        "purely editorial changes.")

    args = parser.parse_args()

    with args.old as f:
        old_tree = etree.parse(f)

    old_accepted, _ = load_xepinfos(old_tree)

    with args.new as f:
        new_tree = etree.parse(f)

    new_accepted, _ = load_xepinfos(new_tree)

    changed = False

    force_archive = set(args.xeps)

    for xep, new_info in new_accepted.items():
        old_version = old_accepted.get(xep, {}).get("last_revision",
                                                    {}).get("version")
        new_version = new_info["last_revision"]["version"]

        if old_version == new_version:
            continue

        force_archive.discard(xep)
        do_archive(args.xeps_dir, args.attic, xep, old_version, new_version)
        changed = True

    for xep in force_archive:
        old_version = old_accepted.get(xep, {}).get("last_revision",
                                                    {}).get("version")
        new_version = new_accepted[xep]["last_revision"]["version"]

        do_archive(args.xeps_dir, args.attic, xep, old_version, new_version)
        changed = True

    if changed:
        print("{}: do not forget to commit & push the attic!".format(
            sys.argv[0]),
              file=sys.stderr)
    else:
        print("{}: nothing to do".format(sys.argv[0]), file=sys.stderr)
Esempio n. 9
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred."
    )

    parser.add_argument(
        "-l", "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to ./build/xeplist.xml)"
    )

    parser.add_argument(
        "-v", "--verbose",
        help="Print additional metadata for deferred XEPs",
        action="store_true",
        default=False,
    )

    parser.add_argument(
        "-m", "--modify",
        default=False,
        metavar="INITIALS",
        help="Modify the to-be-deferred XEPs in-place and use the given "
        "INITIALS in the remarks."
    )

    parser.add_argument(
        "-c", "--commit",
        default=False,
        action="store_true",
        help="Create a git commit for each deferral (only reasonable with -m)"
    )

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("./build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)
    deferred = list(get_deferred(accepted))

    with contextlib.ExitStack() as stack:
        if args.commit:
            stack.enter_context(stash_guard())

        for deferred_info in deferred:
            if args.modify:
                defer_xep(deferred_info["number"],
                          deferred_info["last_revision"]["version"],
                          args.modify)
                if args.commit:
                    subprocess.check_call([
                        "git", "add", "xep-{:04d}.xml".format(
                            deferred_info["number"],
                        ),
                    ])
                    subprocess.check_call([
                        "git", "commit", "-vem",
                        "XEP-{:04d}: deferred due to lack of activity".format(
                            deferred_info["number"],
                        ),
                    ])

            if args.verbose:
                print(
                    "XEP-{info[number]:04d}: {info[title]} "
                    "(last update {info[last_revision][date]:%Y-%m-%d})".format(
                        info=deferred_info
                    )
                )
            else:
                print(deferred_info["number"])
Esempio n. 10
0
File: archive.py Progetto: Zash/xeps
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred."
    )

    parser.add_argument(
        "old",
        type=argparse.FileType("rb"),
        help="Old XEP list"
    )

    parser.add_argument(
        "new",
        type=argparse.FileType("rb"),
        help="New XEP list"
    )

    parser.add_argument(
        "-d", "--xeps-dir",
        type=pathlib.Path,
        default=pathlib.Path.cwd() / "build",
        help="Path to the built XEPs (defaults to ./build)"
    )

    parser.add_argument(
        "-a", "--attic",
        type=pathlib.Path,
        default=pathlib.Path.cwd() / '../xep-attic/content/',
        help="Path to the attic (defaults to ../xep-attic/content/)"
    )

    parser.add_argument(
        "xeps",
        nargs="*",
        type=int,
        help="Additional XEPs (by their number) to archive. Useful for "
        "purely editorial changes."
    )

    args = parser.parse_args()

    with args.old as f:
        old_tree = etree.parse(f)

    old_accepted, _ = load_xepinfos(old_tree)

    with args.new as f:
        new_tree = etree.parse(f)

    new_accepted, _ = load_xepinfos(new_tree)

    changed = False

    force_archive = set(args.xeps)

    for xep, new_info in new_accepted.items():
        old_version = old_accepted.get(xep, {}).get("last_revision", {}).get(
            "version"
        )
        new_version = new_info["last_revision"]["version"]

        if old_version == new_version:
            continue

        force_archive.discard(xep)
        do_archive(args.xeps_dir, args.attic, xep, old_version, new_version)
        changed = True

    for xep in force_archive:
        old_version = old_accepted.get(xep, {}).get("last_revision", {}).get(
            "version"
        )
        new_version = new_accepted[xep]["last_revision"]["version"]

        do_archive(args.xeps_dir, args.attic, xep, old_version, new_version)
        changed = True

    if changed:
        print(
            "{}: do not forget to commit & push the attic!".format(
                sys.argv[0]
            ),
            file=sys.stderr
        )
    else:
        print("{}: nothing to do".format(sys.argv[0]),
              file=sys.stderr)
Esempio n. 11
0
def main():
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "-c",
        "--config",
        metavar="FILE",
        type=argparse.FileType("r"),
        help="Configuration file",
    )
    parser.add_argument(
        "-y",
        dest="ask_confirmation",
        default=True,
        action="store_false",
        help="'I trust this script to do the right thing and send emails"
        "without asking for confirmation.'")
    parser.add_argument(
        "-n",
        "--dry-run",
        dest="dry_run",
        action="store_true",
        default=False,
        help="Instead of sending emails, print them to stdout (implies -y)",
    )

    parser.add_argument(
        "--duration",
        "-d",
        metavar="DAYS",
        default=14,
        help="Duration of the CFE in days (default and at least: 14)",
        type=int,
    )

    parser.add_argument("--xeplist", default=None, type=argparse.FileType("r"))

    parser.add_argument("-x",
                        "--xep",
                        type=int,
                        dest="xeps",
                        action="append",
                        default=[],
                        help="XEP(s) to issue a CFE for")

    parser.add_argument("to",
                        nargs="+",
                        help="The mail addresses to send the update mails to.")

    args = parser.parse_args()

    can_be_interactive = (os.isatty(sys.stdin.fileno())
                          and os.isatty(sys.stdout.fileno()))

    if not args.xeps:
        print("nothing to do (use -x/--xep)", file=sys.stderr)
        sys.exit(1)

    if args.duration < 14:
        print("duration must be at least 14", file=sys.stderr)
        sys.exit(1)

    enddate = (datetime.utcnow() + timedelta(days=args.duration)).date()

    if args.dry_run:
        args.ask_confirmation = False

    if args.ask_confirmation and not can_be_interactive:
        print("Cannot ask for confirmation (stdio is not a TTY), but -y is",
              "not given either. Aborting.",
              sep="\n",
              file=sys.stderr)
        sys.exit(2)

    config = configparser.ConfigParser()
    if args.config is not None:
        config.read_file(args.config)

    if args.xeplist is None:
        args.xeplist = open("build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)
    accepted, _ = load_xepinfos(tree)

    matched_xeps = []
    has_error = False
    for num in args.xeps:
        try:
            info = accepted[num]
        except KeyError:
            print("no such xep: {}".format(num), file=sys.stderr)
            has_error = True
            continue

        if info["status"] != Status.DRAFT:
            print("XEP-{:04d} is in {}, but must be Draft".format(
                num,
                info["status"].value,
            ))
            has_error = True
            continue

        matched_xeps.append(info)

    if has_error:
        sys.exit(1)

    if args.dry_run:
        smtpconn = make_fake_smtpconn()
    else:
        if can_be_interactive:
            interactively_extend_smtp_config(config)

        try:
            smtpconn = make_smtpconn(config)
        except (configparser.NoSectionError,
                configparser.NoOptionError) as exc:
            print("Missing configuration: {}".format(exc), file=sys.stderr)
            print(
                "(cannot ask for configuration on stdio because it is "
                "not a TTY)",
                file=sys.stderr)
            sys.exit(3)

    try:
        for info in matched_xeps:
            mail = make_mail(info, enddate)
            mail["Date"] = datetime.utcnow()
            mail["From"] = config.get("smtp", "from")
            mail["To"] = args.to

            if args.ask_confirmation:
                print()
                print("---8<---")
                print(mail.as_string())
                print("--->8---")
                print()
                choice = choose(
                    "Send this email? [y]es, [n]o, [a]bort: ",
                    "yna",
                    eof="a",
                )

                if choice == "n":
                    continue
                elif choice == "a":
                    print("Exiting on user request.", file=sys.stderr)
                    sys.exit(4)

            smtpconn.send_message(mail)
    finally:
        smtpconn.close()
Esempio n. 12
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred.")

    parser.add_argument("old",
                        type=argparse.FileType("rb"),
                        help="Old XEP list")

    parser.add_argument("new",
                        type=argparse.FileType("rb"),
                        help="New XEP list")

    parser.add_argument("-d",
                        "--xeps-dir",
                        type=pathlib.Path,
                        default=pathlib.Path.cwd() / "build",
                        help="Path to the built XEPs (defaults to ./build)")

    parser.add_argument(
        "-a",
        "--attic",
        type=pathlib.Path,
        default=pathlib.Path.cwd() / '../xep-attic/content/',
        help="Path to the attic (defaults to ../xep-attic/content/)")

    args = parser.parse_args()

    with args.old as f:
        old_tree = etree.parse(f)

    old_accepted, _ = load_xepinfos(old_tree)

    with args.new as f:
        new_tree = etree.parse(f)

    new_accepted, _ = load_xepinfos(new_tree)

    changed = False

    for xep, new_info in new_accepted.items():
        old_version = old_accepted.get(xep, {}).get("last_revision",
                                                    {}).get("version")
        new_version = new_info["last_revision"]["version"]

        if old_version == new_version:
            continue

        curr_file = args.xeps_dir / "xep-{:04d}.html".format(xep)
        attic_file = args.attic / "xep-{:04d}-{}.html".format(xep, new_version)

        print("XEP-{:04d}:".format(xep), old_version, "->", new_version)

        shutil.copy(str(curr_file), str(attic_file))
        changed = True

    if changed:
        print("{}: do not forget to commit & push the attic!".format(
            sys.argv[0]),
              file=sys.stderr)
    else:
        print("{}: nothing to do".format(sys.argv[0]), file=sys.stderr)
Esempio n. 13
0
def main():
    import argparse

    parser = argparse.ArgumentParser(description="Accept an inbox XEP.")

    parser.add_argument(
        "-l",
        "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to {})".format(DEFAULT_XEPLIST_PATH))

    parser.add_argument(
        "-y",
        "--yes",
        dest="ask",
        action="store_false",
        help="Assume default answer to all questions.",
        default=True,
    )

    parser.add_argument(
        "-f",
        "--force",
        dest="force",
        action="store_true",
        default=False,
        help="Force acceptance even if suspicious.",
    )

    parser.add_argument(
        "-c",
        "--commit",
        default=False,
        action="store_true",
        help="Make a git commit",
    )

    parser.add_argument("item", help="Inbox name")

    parser.add_argument("votedate",
                        type=isodate,
                        help="The date of the vote, in ISO format (%Y-%m-%d).")

    parser.add_argument("initials", help="Your editor initials")

    args = parser.parse_args()

    if args.item.endswith(".xml"):
        # strip the path
        p = pathlib.Path(args.item)
        args.item = p.parts[-1].rsplit(".")[0]

    if args.xeplist is None:
        args.xeplist = open(DEFAULT_XEPLIST_PATH, "rb")

    if args.xeplist is not None:
        with args.xeplist as f:
            tree = etree.parse(f)
        accepted, inbox = load_xepinfos(tree)

    try:
        xepinfo = inbox[args.item]
    except KeyError:
        print("no such inbox xep: {!r}".format(args.item), file=sys.stderr)
        print("maybe run make build/xeplist.xml first?", file=sys.stderr)
        sys.exit(1)

    new_number = get_next_xep_number(accepted)

    new_filename = pathlib.Path(".") / "xep-{:04d}.xml".format(new_number)
    inbox_path = pathlib.Path("inbox") / "{}.xml".format(args.item)
    if new_filename.exists():
        raise FileExistsError(
            "Internal error: XEP file does already exist! ({})".format(
                new_filename))
    if not inbox_path.exists():
        print("inbox file does not exist or is not readable: {}".format(
            inbox_path))

    if args.ask:
        print("I am going to accept:")
        print()
        print("  Title: {!r}".format(xepinfo["title"]))
        print("  Abstract: {!r}".format(xepinfo["abstract"]))
        print("  Last Revision: {} ({})".format(
            xepinfo["last_revision"]["date"].date(),
            xepinfo["last_revision"]["version"],
        ))
        print()
        print("as new XEP-{:04d}.".format(new_number))
        print()
        choice = choose("Is this correct? [y]es, [n]o: ", "yn", eof="n")
        if choice != "y":
            print("aborted at user request")
            sys.exit(2)

    shutil.copy(str(inbox_path), str(new_filename))

    accept_xep(new_number, xepinfo["last_revision"]["version"], args.initials,
               xepinfo["approver"], args.votedate.date())

    if args.commit:
        subprocess.check_call([
            "git",
            "reset",
            "HEAD",
            ".",
        ])
        subprocess.check_call([
            "git",
            "add",
            new_filename.parts[-1],
        ])
        if args.ask:
            flags = ["-ve"]
        else:
            flags = []
        subprocess.check_call([
            "git", "commit", "-m", "Accept {} as XEP-{:04}".format(
                inbox_path,
                new_number,
            )
        ] + flags)
Esempio n. 14
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Show the XEPs which need to be changed to deferred.")

    parser.add_argument(
        "-l",
        "--xeplist",
        type=argparse.FileType("rb"),
        default=None,
        help="XEP list to use (defaults to ./build/xeplist.xml)")

    parser.add_argument(
        "-v",
        "--verbose",
        help="Print additional metadata for deferred XEPs",
        action="store_true",
        default=False,
    )

    parser.add_argument(
        "-m",
        "--modify",
        default=False,
        metavar="INITIALS",
        help="Modify the to-be-deferred XEPs in-place and use the given "
        "INITIALS in the remarks.")

    parser.add_argument(
        "--no-revision",
        dest="insert_revision",
        action="store_false",
        default=True,
        help="Do not create a revision block",
    )

    parser.add_argument(
        "-c",
        "--commit",
        default=False,
        action="store_true",
        help="Create a git commit for each deferral (only reasonable with -m)")

    args = parser.parse_args()

    if args.xeplist is None:
        args.xeplist = open("./build/xeplist.xml", "rb")

    with args.xeplist as f:
        tree = etree.parse(f)

    accepted, _ = load_xepinfos(tree)
    deferred = list(get_deferred(accepted))

    with contextlib.ExitStack() as stack:
        if args.commit:
            stack.enter_context(stash_guard())

        for deferred_info in deferred:
            if args.modify:
                defer_xep(deferred_info["number"],
                          deferred_info["last_revision"]["version"],
                          args.modify, args.insert_revision)
                if args.commit:
                    subprocess.check_call([
                        "git",
                        "add",
                        "xep-{:04d}.xml".format(deferred_info["number"], ),
                    ])
                    commit_argv = [
                        "git", "commit", "-vm",
                        "XEP-{:04d}: deferred due to lack of activity".format(
                            deferred_info["number"], )
                    ]
                    if args.insert_revision:
                        commit_argv.append("-e")
                    subprocess.check_call(commit_argv)

            if args.verbose:
                print("XEP-{info[number]:04d}: {info[title]} "
                      "(last update {info[last_revision][date]:%Y-%m-%d})".
                      format(info=deferred_info))
            else:
                print(deferred_info["number"])
Esempio n. 15
0
def main():
    import argparse

    parser = argparse.ArgumentParser(
        description=wraptext(DESCRIPTION),
        epilog=wraptext(EPILOG),
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "-c", "--config",
        metavar="FILE",
        type=argparse.FileType("r"),
        help="Configuration file",
    )
    parser.add_argument(
        "-y",
        dest="ask_confirmation",
        default=True,
        action="store_false",
        help="'I trust this script to do the right thing and send emails"
        "without asking for confirmation.'"
    )
    parser.add_argument(
        "--no-proto",
        dest="process_proto",
        default=True,
        action="store_false",
        help="Disable processing of ProtoXEPs.",
    )
    parser.add_argument(
        "-n", "--dry-run",
        dest="dry_run",
        action="store_true",
        default=False,
        help="Instead of sending emails, print them to stdout (implies -y)",
    )

    parser.add_argument(
        "old",
        type=argparse.FileType("rb"),
        help="Old xep-infos XML file",
    )
    parser.add_argument(
        "new",
        type=argparse.FileType("rb"),
        help="New xep-infos XML file",
    )

    parser.add_argument(
        "to",
        nargs="+",
        help="The mail addresses to send the update mails to."
    )

    args = parser.parse_args()

    can_be_interactive = (
        os.isatty(sys.stdin.fileno()) and
        os.isatty(sys.stdout.fileno())
    )

    if args.dry_run:
        args.ask_confirmation = False

    if args.ask_confirmation and not can_be_interactive:
        print("Cannot ask for confirmation (stdio is not a TTY), but -y is",
              "not given either. Aborting.", sep="\n", file=sys.stderr)
        sys.exit(2)

    config = configparser.ConfigParser()
    if args.config is not None:
        config.read_file(args.config)

    with args.old as f:
        tree = etree.parse(f)
    old_accepted, old_proto = load_xepinfos(tree)

    with args.new as f:
        tree = etree.parse(f)
    new_accepted, new_proto = load_xepinfos(tree)

    old_xeps = set(old_accepted.keys())
    new_xeps = set(new_accepted.keys())

    common_xeps = old_xeps & new_xeps
    added_xeps = new_xeps - old_xeps

    added_protos = set(new_proto.keys()) - set(old_proto.keys())

    updates = []

    for common_xep in common_xeps:
        old_info = old_accepted[common_xep]
        new_info = new_accepted[common_xep]

        action = diff_infos(old_info, new_info)
        if action is not None:
            updates.append((common_xep, action, new_info))

    for added_xep in added_xeps:
        old_info = dummy_info(added_xep)
        new_info = new_accepted[added_xep]

        action = diff_infos(old_info, new_info)
        if action is not None:
            updates.append((added_xep, action, new_info))

    if args.process_proto:
        for added_proto in added_protos:
            old_info = dummy_info('xxxx')
            new_info = new_proto[added_proto]

            action = diff_infos(old_info, new_info)
            if action is not None:
                updates.append((added_proto, action, new_info))

    if args.dry_run:
        smtpconn = make_fake_smtpconn()
    else:
        if can_be_interactive:
            interactively_extend_smtp_config(config)

        try:
            smtpconn = make_smtpconn(config)
        except (configparser.NoSectionError,
                configparser.NoOptionError) as exc:
            print("Missing configuration: {}".format(exc),
                  file=sys.stderr)
            print("(cannot ask for configuration on stdio because it is "
                  "not a TTY)", file=sys.stderr)
            sys.exit(3)

    try:
        for id_, action, info in updates:
            if action == Action.PROTO:
                mail = make_proto_mail(info)
            else:
                mail = make_nonproto_mail(action, info)
            mail["Date"] = datetime.utcnow()
            mail["From"] = config.get("smtp", "from")
            mail["To"] = args.to

            if args.ask_confirmation:
                print()
                print("---8<---")
                print(mail.as_string())
                print("--->8---")
                print()
                choice = choose(
                    "Send this email? [y]es, [n]o, [a]bort: ",
                    "yna",
                    eof="a",
                )

                if choice == "n":
                    continue
                elif choice == "a":
                    print("Exiting on user request.", file=sys.stderr)
                    sys.exit(4)

            smtpconn.send_message(mail)
    finally:
        smtpconn.close()