Skip to content

Commit

Permalink
Dune2 formatting (#2347)
Browse files Browse the repository at this point in the history
Dune2 formatting
  • Loading branch information
rgrinberg authored Aug 6, 2019
2 parents 30b9a23 + 3a8b859 commit 046148a
Show file tree
Hide file tree
Showing 22 changed files with 346 additions and 110 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
- Change the automatically generated odoc index to only list public modules.
This only affects unwrapped libraries (#2479, @rgrinberg)

- Set up formatting rules by default. They can be configured through a new
`(formatting)` stanza in `dune-project` (#2347, fixes #2315, @emillon)

1.11.0 (23/07/2019)
-------------------

Expand Down
45 changes: 35 additions & 10 deletions doc/formatting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ Furthermore it can be used to format code of any defined dialect (see
.. _ocamlformat: https://github.com/ocaml-ppx/ocamlformat
.. _refmt: https://github.com/facebook/reason/tree/master/src/refmt

Enabling automatic formatting
=============================
Configuring automatic formatting (dune 2.0)
===========================================

This feature is enabled by adding the following to the ``dune-project`` file:
If using ``(lang dune 2.0)``, there is nothing to do, formatting will be set up
by default. It is possible to disable it by adding the following to
``dune-project``:

.. code:: scheme
(using fmt 1.2)
(formatting disabled)
Formatting a project
====================
Expand Down Expand Up @@ -64,24 +66,47 @@ avoid pulling ``ocamlformat`` as a dependency.
In these cases, it is possible to use the ``enabled_for`` argument to restrict
the languages that are considered for formatting.

.. code:: scheme
(formatting (enabled_for reason))
Enabling and configuring automatic formatting (dune 1.x)
========================================================

.. note:: This section applies only to projects with ``(lang dune 1.x)``.

In ``(lang dune 1.x)``, no formatting is done by default. This feature is
enabled by adding the following to the ``dune-project`` file:

.. code:: scheme
(using fmt 1.2)
Languages can be configured using the following syntax:

.. code:: scheme
(using fmt 1.2 (enabled_for reason))
Version history
===============

1.2
---
(lang dune 2.0)
---------------

* Formatting is enabled by default.

(using fmt 1.2)
---------------

* Format :ref:`dialects-main`.

1.1
---
(using fmt 1.1)
---------------

* Format Dune files.

1.0
---
(using fmt 1.0)
---------------

* Format OCaml (using ocamlformat_) and Reason (using refmt_) source code.
76 changes: 0 additions & 76 deletions src/dune_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -623,82 +623,6 @@ end

let modules_field name = Ordered_set_lang.field name

module Auto_format = struct
let syntax =
Syntax.create ~name:"fmt"
~desc:"integration with automatic formatters"
[ (1, 2) ]

type language =
| Dialect of string
| Dune

let language_to_dyn =
let open Dyn.Encoder in
function
| Dialect name -> constr "dialect" [string name]
| Dune -> constr "dune" []

let language = function
| "dune" -> Dune
| s -> Dialect s

type enabled_for =
| Default of Syntax.Version.t
| Only of language list

let enabled_for_field =
let+ r = field_o "enabled_for" (repeat (map ~f:language string))
and+ version = Syntax.get_exn syntax
in
match r with
| Some l -> Only l
| None -> Default version

let enabled_for_to_dyn =
let open Dyn.Encoder in
function
| Default v -> constr "default" [Syntax.Version.to_dyn v]
| Only l -> constr "only" (List.map ~f:language_to_dyn l)

type t =
{ loc : Loc.t
; enabled_for : enabled_for
}

let to_dyn {enabled_for; loc = _} =
let open Dyn.Encoder in
record ["enabled_for", enabled_for_to_dyn enabled_for]

let dparse_args =
let+ loc = loc
and+ enabled_for = fields enabled_for_field
in
({loc; enabled_for}, [])

let key =
Dune_project.Extension.register syntax dparse_args to_dyn

let includes config =
match config.enabled_for with
| Default ver ->
let in_1_0 =
[Dialect "ocaml"; Dialect "reason"]
in
begin match Syntax.Version.compare ver (1, 1) with
| Lt ->
fun language -> List.mem language ~set:in_1_0
| Eq ->
fun language -> List.mem language ~set:(Dune :: in_1_0)
| Gt ->
fun _ -> true
end
| Only l ->
fun language -> List.mem language ~set:l

let loc t = t.loc
end

module Buildable = struct
type t =
{ loc : Loc.t
Expand Down
14 changes: 0 additions & 14 deletions src/dune_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,6 @@ module Dep_conf : sig
val to_dyn : t Dyn.Encoder.t
end

module Auto_format : sig
type language =
| Dialect of string
| Dune

type t

val key : t Dune_project.Extension.t

val loc : t -> Loc.t

val includes : t -> language -> bool
end

module Buildable : sig
type t =
{ loc : Loc.t
Expand Down
19 changes: 18 additions & 1 deletion src/dune_project.ml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ type t =
; file_key : File_key.t
; dialects : Dialect.DB.t
; explicit_js_mode : bool
; format_config : Format_config.t option
}

let equal = (==)
Expand Down Expand Up @@ -243,7 +244,7 @@ let to_dyn
; extension_args = _; stanza_parser = _ ; packages
; implicit_transitive_deps ; wrapped_executables ; dune_version
; allow_approx_merlin ; generate_opam_files
; file_key ; dialects ; explicit_js_mode } =
; file_key ; dialects ; explicit_js_mode ; format_config } =
let open Dyn.Encoder in
record
[ "name", Name.to_dyn name
Expand All @@ -269,6 +270,7 @@ let to_dyn
; "file_key", string file_key
; "dialects", Dialect.DB.to_dyn dialects
; "explicit_js_mode", bool explicit_js_mode
; "format_config", (option Format_config.to_dyn) format_config
]

let find_extension_args t key =
Expand Down Expand Up @@ -537,6 +539,17 @@ let wrapped_executables_default ~(lang : Lang.Instance.t) =
let explicit_js_mode_default ~(lang : Lang.Instance.t) =
lang.version >= (2, 0)

let format_extension_key =
Extension.register
Format_config.syntax
Format_config.dparse_args
Format_config.to_dyn

let format_config t =
let ext = find_extension_args t format_extension_key in
let dune_lang = t.format_config in
Format_config.of_config ~ext ~dune_lang

let anonymous = lazy (
let lang = get_dune_lang () in
let name = Name.anonymous_root in
Expand Down Expand Up @@ -578,6 +591,7 @@ let anonymous = lazy (
; file_key
; dialects = Dialect.DB.builtin
; explicit_js_mode
; format_config = None
})

let default_name ~dir ~packages =
Expand Down Expand Up @@ -648,6 +662,7 @@ let parse ~dir ~lang ~opam_packages ~file =
(Syntax.since Stanza.syntax (1, 11) >>> located Dialect.decode)
and+ explicit_js_mode =
field_o_b "explicit_js_mode" ~check:(Syntax.since Stanza.syntax (1, 11))
and+ format_config = Format_config.field
in
let homepage =
match homepage, source with
Expand Down Expand Up @@ -767,6 +782,7 @@ let parse ~dir ~lang ~opam_packages ~file =
; generate_opam_files
; dialects
; explicit_js_mode
; format_config
})

let load_dune_project ~dir opam_packages =
Expand Down Expand Up @@ -816,6 +832,7 @@ let make_jbuilder_project ~dir opam_packages =
; wrapped_executables = false
; dialects
; explicit_js_mode = false
; format_config = None
}

let load ~dir ~files =
Expand Down
1 change: 1 addition & 0 deletions src/dune_project.mli
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ val allow_approx_merlin : t -> bool
val generate_opam_files : t -> bool
val dialects : t -> Dialect.DB.t
val explicit_js_mode : t -> bool
val format_config : t -> Format_config.t option

val equal : t -> t -> bool
val hash : t -> int
Expand Down
Loading

0 comments on commit 046148a

Please sign in to comment.