Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: formatting did not stabilize after 10 iterations #2587

Open
hannesm opened this issue Oct 14, 2024 · 4 comments
Open

Bug: formatting did not stabilize after 10 iterations #2587

hannesm opened this issue Oct 14, 2024 · 4 comments

Comments

@hannesm
Copy link

hannesm commented Oct 14, 2024

Describe the bug

I've no clue how to describe it, but:

val register : 'a Cmdliner.Term.t -> (unit -> 'a)
[@@ocamlformat "disable"]
(* the return value is (unit -> 'a), let's keep the parens although they're
   superfluous. *)
[@@ocaml.deprecated "Use Mirage_runtime.register_arg instead."]

Leads to

ocamlformat: Cannot process "lib_runtime/mirage_runtime.mli".
  Please report this bug at https://github.com/ocaml-ppx/ocamlformat/issues.
  BUG: formatting did not stabilize after 10 iterations.

How to Reproduce

See above, ocamlformat configuration:

version = 0.26.2
profile = conventional
break-infix = fit-or-vertical
parse-docstrings = true
@Julow
Copy link
Collaborator

Julow commented Oct 14, 2024

I fail to reproduce the bug with 0.26.2. Can you share the entire code file ?

@hannesm
Copy link
Author

hannesm commented Oct 14, 2024

sure:

(*
 * Copyright (c) 2014 David Sheets <[email protected]>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *)

open Cmdliner

(** Mirage runtime utilities.

    {e Release %%VERSION%%} *)

(** {2 Log thresholds} *)

type log_threshold = [ `All | `Src of string ] * Logs.level option
(** The type for log threshold. A log level of [None] disables logging. *)

val set_level : default:Logs.level option -> log_threshold list -> unit
(** [set_level ~default l] set the log levels needed to have all of the log
    sources appearing in [l] be used. *)

val logs : log_threshold list Term.t
(** [logs] is a command-liner term for setting the log_threshold. *)

(** {2 Command-line converters} *)
module Conv : sig
  val log_threshold : log_threshold Cmdliner.Arg.conv
  (** [log_threshold] converts log reporter threshold. *)
end

(** {2 Manpage sections} *)
val s_net : string
(** [s_net] is used for network options. *)

val s_disk : string
(** [s_disk] is used for disk options. *)

val s_log : string
(** [s_log] is used for logging and monitoring options. *)

(** {3 Blocks} *)

val disk : string Term.t
val analyze : bool Term.t

(** {3 Startup delay} *)

val delay : int Term.t
(** The initial delay, specified in seconds, before a unikernel starting up.
    Defaults to 0. Useful for tenders and environments that take some time to
    bring devices up. *)

(** {2 Registering scheduler hooks} *)

val at_exit : (unit -> unit Lwt.t) -> unit
(** [at_exit hook] registers [hook], which will be executed before the unikernel
    exits. The first hook registered will be executed last. *)

val at_enter_iter : (unit -> unit) -> unit
(** [at_enter_iter hook] registers [hook] to be executed at the beginning of
    each event loop iteration. The first hook registered will be executed last.

    If [hook] calls {!at_enter_iter} recursively, the new hook will run only on
    the next event loop iteration. *)

val at_leave_iter : (unit -> unit) -> unit
(** [at_leave_iter hook] registers [hook] to be executed at the end of each
    event loop iteration. See {!at_enter_iter} for details. *)

(** {2 Running hooks} *)

(** This is mainly for for developers implementing new targets. *)

val run_exit_hooks : unit -> unit Lwt.t
(** [run_exit_hooks ()] calls the sequence of hooks registered with {!at_exit}
    in sequence. *)

val run_enter_iter_hooks : unit -> unit
(** [run_enter_iter_hooks ()] calls the sequence of hooks registered with
    {!at_enter_iter} in sequence. *)

val run_leave_iter_hooks : unit -> unit
(** [run_leave_iter_hooks ()] call the sequence of hooks registered with
    {!at_leave_iter} in sequence. *)

(** {2 Exit Codes} *)

val argument_error : int
(** [argument_error] is the exit code used for argument parsing errors: 64. *)

val help_version : int
(** [help_version] is the exit code used when help/version is used: 63. *)

val register_arg : 'a Cmdliner.Term.t -> (unit -> 'a)
[@@ocamlformat "disable"]
(* the return value is (unit -> 'a), let's keep the parens although they're
   superfluous. *)
(** [register_arg term] registers term to be evaluated at boot time. An example
    is: [let hello = register_arg <myterm>] (at the toplevel of the unikernel),
    and in the unikernel code
    [Logs.info (fun m -> m "hello argument is: %s" (hello ()))]. *)

(** / *)

val with_argv : unit Cmdliner.Term.t list -> string -> string array -> unit
val runtime_args : unit -> unit Cmdliner.Term.t list

val register : 'a Cmdliner.Term.t -> (unit -> 'a)
[@@ocamlformat "disable"]
(* the return value is (unit -> 'a), let's keep the parens although they're
   superfluous. *)
[@@ocaml.deprecated "Use Mirage_runtime.register_arg instead."]

As a workaround, I put the comment before the [@@ocamlformat "disable"] attribute.

@Julow
Copy link
Collaborator

Julow commented Oct 15, 2024

Thanks! The issue is on

val register_arg : 'a Cmdliner.Term.t -> (unit -> 'a)
[@@ocamlformat "disable"]
(* the return value is (unit -> 'a), let's keep the parens although they're
   superfluous. *)
(** [register_arg term] registers term to be evaluated at boot time. An example
    is: [let hello = register_arg <myterm>] (at the toplevel of the unikernel),
    and in the unikernel code
    [Logs.info (fun m -> m "hello argument is: %s" (hello ()))]. *)

It also happens in structures:

let x _ = ()
[@@ocamlformat "disable"]
(* the return value is (unit -> 'a), let's keep the parens although they're
   superfluous. *)
(** [register_arg term] registers term to be evaluated at boot time. An example
   is: [let hello = register_arg <myterm>] (at the toplevel of the unikernel),
   and in the unikernel code
   [Logs.info (fun m -> m "hello argument is: %s" (hello ()))]. *)

@hhugo
Copy link
Collaborator

hhugo commented Nov 14, 2024

#2457

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants