From aaf2985832c08b1e187364b3ad2921bd524f88e2 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Thu, 13 Jul 2023 01:29:13 +0200 Subject: [PATCH] changelog creator Signed-off-by: Ali Caglayan --- .gitignore | 3 ++ Makefile | 10 ++++++ doc/changes/add.ml | 73 +++++++++++++++++++++++++++++++++++++ doc/changes/add.t | 89 ++++++++++++++++++++++++++++++++++++++++++++++ doc/changes/dune | 25 +++++++++++++ doc/hacking.rst | 12 +++++++ 6 files changed, 212 insertions(+) create mode 100644 doc/changes/add.ml create mode 100644 doc/changes/add.t create mode 100644 doc/changes/dune diff --git a/.gitignore b/.gitignore index 218cfd7be696..423d908b534a 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ nix/profiles/ # dkml desktop CI /msys64 /.ci + +# changelog username +doc/changes/username diff --git a/Makefile b/Makefile index 962f598c7d6d..6a184a6e3a6e 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,16 @@ dev-switch: opam switch create -y . $(TEST_OCAMLVERSION) --deps-only --with-test opam install -y --update-invariant ocaml.$(TEST_OCAMLVERSION) $(TEST_DEPS) $(DEV_DEPS) +.PHONY: changelog +changelog: + $(BIN) exec -- doc/changes/add.exe + +.PHONY: compile-changelog +compile-changelog: + - $(BIN) build @doc/changes/compile-changelog + $(BIN) promote + rm -rf doc/changes/unreleased + .PHONY: test test: $(BIN) $(BIN) runtest diff --git a/doc/changes/add.ml b/doc/changes/add.ml new file mode 100644 index 000000000000..9cc3e3a72e5e --- /dev/null +++ b/doc/changes/add.ml @@ -0,0 +1,73 @@ +open Stdune +module Console = Dune_console + +(** This script generates a changelog entry for a PR. It asks the user for + information about the pull request and then generates a file in the + [output_directory]. *) + +let changes_directory = Path.source (Path.Source.of_string "doc/changes") + +let output_directory = + Path.append_local changes_directory (Path.Local.of_string "unreleased") + +let username_file = + Path.append_local changes_directory (Path.Local.of_string "username") + +let () = + let description = + Console.printf "What is the change about?"; + read_line () + in + let pr_number = + Console.printf "PR number? (Leave blank if you don't know)"; + match read_line () with + | "" -> "????" + | s -> s + in + let username = + if (Path.stat_exn username_file).st_kind = Unix.S_REG then ( + Console.printf "Using username from %s." + (Path.to_string_maybe_quoted username_file); + let raw_username = Io.read_file username_file in + String.trim raw_username) + else ( + Console.printf "What is your username? (This will be saved for later)"; + let username = read_line () in + Path.mkdir_p output_directory; + Io.write_file username_file username; + username) + in + let issues = + Console.printf "Which issue numbers does this change fix?"; + match read_line () with + | "" -> "" + | s -> + String.split ~on:' ' s + |> List.map ~f:(fun s -> "#" ^ s) + |> String.enumerate_and + |> fun x -> ", fixes " ^ x + in + let pp = + Pp.concat + [ Pp.verbatim "- " + ; Pp.box + (Pp.textf "%s (#%s%s, @%s)" description pr_number issues username) + ; Pp.newline + ] + in + let entry_file = + Path.append_source output_directory + (Path.Source.of_string (pr_number ^ "_" ^ username)) + in + if Path.exists entry_file then ( + Console.print_user_message + (User_error.make + [ Pp.textf "File %s already exists." + (Path.to_string_maybe_quoted entry_file) + ]); + exit 1) + else + Console.printf "Changelog entry in: %s" + (Path.to_string_maybe_quoted entry_file); + Path.mkdir_p output_directory; + Io.write_lines entry_file [ Format.asprintf "%a" Pp.to_fmt pp ] diff --git a/doc/changes/add.t b/doc/changes/add.t new file mode 100644 index 000000000000..9de68950872e --- /dev/null +++ b/doc/changes/add.t @@ -0,0 +1,89 @@ +Testing the changelog adding script + + $ cat > user_response << EOF + > Changelog description that is long enough to be wrapped to the next line + > 1234 + > SomeGitHubUser + > 123 456 789 + > EOF + + $ ./add.exe < user_response + What is the change about? + PR number? (Leave blank if you don't know) + What is your username? (This will be saved for later) + Which issue numbers does this change fix? + Changelog entry in: doc/changes/unreleased/1234_SomeGitHubUser + + $ ls doc/changes/unreleased + 1234_SomeGitHubUser + $ cat doc/changes/unreleased/* + - Changelog description that is long enough to be wrapped to the next line + (#1234, fixes #123, #456 and #789, @SomeGitHubUser) + + +The username gets recorded in doc/changes/username + + $ cat doc/changes/username + SomeGitHubUser + +Omitted the PR number and issues. Also reusing the saved username. + + $ cat > user_response << EOF + > Changelog description that is long enough to be wrapped to the next line. \ + > This one takes the cake for being especially long and wrappable. + > + > + > EOF + + $ ./add.exe < user_response + What is the change about? + PR number? (Leave blank if you don't know) + Using username from doc/changes/username. + Which issue numbers does this change fix? + Changelog entry in: doc/changes/unreleased/????_SomeGitHubUser + + $ ls doc/changes/unreleased + 1234_SomeGitHubUser + ????_SomeGitHubUser + $ cat doc/changes/unreleased/* + - Changelog description that is long enough to be wrapped to the next line + (#1234, fixes #123, #456 and #789, @SomeGitHubUser) + + - Changelog description that is long enough to be wrapped to the next line. + This one takes the cake for being especially long and wrappable. (#????, + @SomeGitHubUser) + +To use another username, simply delete the doc/changes/username file. + + $ rm doc/changes/username + +This time we also omit the PR number and give the same username to cause a +conflict with the entry. + + $ cat > user_response << EOF + > Another really long changelog description with some information that makes \ + > it long enough to wrap to the next line. + > + > SomeGitHubUser + > 1234 7809 + > EOF + + $ ./add.exe < user_response + What is the change about? + PR number? (Leave blank if you don't know) + What is your username? (This will be saved for later) + Which issue numbers does this change fix? + Error: File doc/changes/unreleased/????_SomeGitHubUser already exists. + [1] + +In this case, the ????_SomeGithubUser file should have already been renamed +since the PR should be known by now. (? should be quoted in the shell) + $ (cd doc/changes/unreleased/ && mv "????_SomeGitHubUser" 7890_SomeGitHubUser) + + $ ./add.exe < user_response + What is the change about? + PR number? (Leave blank if you don't know) + Using username from doc/changes/username. + Which issue numbers does this change fix? + Changelog entry in: doc/changes/unreleased/????_SomeGitHubUser + diff --git a/doc/changes/dune b/doc/changes/dune new file mode 100644 index 000000000000..e71271c44987 --- /dev/null +++ b/doc/changes/dune @@ -0,0 +1,25 @@ +(executable + (name add) + (libraries stdune pp dune_console)) + +(cram + (deps add.exe)) + +(rule + (alias compile-changelog) + (deps + (glob_files unreleased/*)) + (action + (with-stdout-to + changes-new.md + (progn + (echo "Unreleased\n") + (echo "----------\n") + (echo "\n") + (cat %{deps}) + (cat ../../CHANGES.md))))) + +(rule + (alias compile-changelog) + (action + (diff ../../CHANGES.md changes-new.md))) diff --git a/doc/hacking.rst b/doc/hacking.rst index eb0ebba7114b..5757039dd5ae 100644 --- a/doc/hacking.rst +++ b/doc/hacking.rst @@ -406,6 +406,18 @@ For project names, use the following capitalization: - **PPX,** rather than ppx or Ppx; ``ppxlib`` - **UTop,** rather than utop or Utop. +Changelog +========= + +All changes observable by the user should be documented in the changelog. + +Use ``make changelog`` to run an interactive script for adding a changelog +entry. Unreleased changes are collected in their own files in the +``doc/changes/unreleased`` directory. + +During the release process, the changelog entries will be compiled into +``CHANGES.md``. + Vendoring =========