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

Add a default alias #926

Merged
4 commits merged into from Jul 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ next

- Version `dune-workspace` and `~/.config/dune/config` files (#..., @diml)

- Add the ability to build an alias non-recursively from the command
line by writing `@@alias` (#926, @diml)

- Add a special `default` alias that defaults to `(alias_rec install)`
when not defined by the user and make `@@default` be the default
target (#926, @diml)

1.0+beta20 (10/04/2018)
-----------------------

Expand Down
92 changes: 67 additions & 25 deletions bin/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type common =
; (* Original arguments for the external-lib-deps hint *)
orig_args : string list
; config : Config.t
; default_target : string
}

let prefix_target common s = common.target_prefix ^ s
Expand Down Expand Up @@ -114,28 +115,34 @@ end

type target =
| File of Path.t
| Alias of Path.t
| Alias_rec of Path.t

let parse_alias path ~contexts =
let dir = Path.parent_exn path in
let name = Path.basename path in
match Path.extract_build_context dir with
| None -> (contexts, dir, name)
| Some ("install", _) ->
die "Invalid alias: %s.\n\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful to pass a loc to have a nicer error message? (or return a result from here)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from the command line, so we don't have a loc for it.

There are no aliases in %s."
(Path.to_string_maybe_quoted Path.(relative build_dir "install"))
(Path.to_string_maybe_quoted path)
| Some (ctx, dir) -> ([ctx], dir, name)

let request_of_targets (setup : Main.setup) targets =
let open Build.O in
let contexts = List.map setup.contexts ~f:(fun c -> c.Context.name) in
List.fold_left targets ~init:(Build.return ()) ~f:(fun acc target ->
acc >>>
match target with
| File path -> Build.path path
| Alias path ->
let contexts, dir, name = parse_alias path ~contexts in
Build_system.Alias.dep_multi_contexts ~dir ~name
~file_tree:setup.file_tree ~contexts
| Alias_rec path ->
let dir = Path.parent_exn path in
let name = Path.basename path in
let contexts, dir =
match Path.extract_build_context dir with
| None -> (contexts, dir)
| Some ("install", _) ->
die "Invalid alias: %s.\n\
There are no aliases in %s."
(Path.to_string_maybe_quoted Path.(relative build_dir "install"))
(Path.to_string_maybe_quoted path)
| Some (ctx, dir) -> ([ctx], dir)
in
let contexts, dir, name = parse_alias path ~contexts in
Build_system.Alias.dep_rec_multi_contexts ~dir ~name
~file_tree:setup.file_tree ~contexts)

Expand Down Expand Up @@ -228,6 +235,7 @@ let common =
ignore_promoted_rules,
config_file,
profile,
default_target,
orig)
x
display
Expand Down Expand Up @@ -290,6 +298,7 @@ let common =
; x
; config
; build_dir
; default_target
}
in
let docs = copts_sect in
Expand Down Expand Up @@ -478,6 +487,20 @@ let common =
in
Term.(ret (const merge $ config_file $ no_config))
in
let default_target_default =
match Which_program.t with
| Dune -> "@@default"
| Jbuilder -> "@install"
in
let default_target =
Arg.(value
& opt (some string) None
& info ["default-target"] ~docs ~docv:"TARGET"
~doc:(sprintf
{|Set the default target that when none is specified to
$(b,dune build). It defaults to %s.|}
default_target_default))
in
let for_release = "for-release-of-packages" in
let frop =
Arg.(value
Expand All @@ -490,33 +513,37 @@ let common =
packages as well as getting reproducible builds.|})
in
let merge root only_packages ignore_promoted_rules
(config_file_opt, config_file) profile release =
(config_file_opt, config_file) profile default_target release =
let fail opt = incompatible ("-p/--" ^ for_release) opt in
match release, root, only_packages, ignore_promoted_rules,
profile, config_file_opt with
| Some _, Some _, _, _, _, _ -> fail "--root"
| Some _, _, Some _, _, _, _ -> fail "--only-packages"
| Some _, _, _, true , _, _ -> fail "--ignore-promoted-rules"
| Some _, _, _, _, Some _, _ -> fail "--profile"
| Some _, _, _, _, _, Some s -> fail s
| Some pkgs, None, None, false, None, None ->
profile, default_target, config_file_opt with
| Some _, Some _, _, _, _, _, _ -> fail "--root"
| Some _, _, Some _, _, _, _, _ -> fail "--only-packages"
| Some _, _, _, true , _, _, _ -> fail "--ignore-promoted-rules"
| Some _, _, _, _, Some _, _, _ -> fail "--profile"
| Some _, _, _, _, _, Some s, _ -> fail s
| Some _, _, _, _, _, _, Some _ -> fail "--default-target"
| Some pkgs, None, None, false, None, None, None ->
`Ok (Some ".",
Some pkgs,
true,
No_config,
Some "release",
"@install",
["-p"; pkgs]
)
| None, _, _, _, _, _ ->
| None, _, _, _, _, _, _ ->
`Ok (root,
only_packages,
ignore_promoted_rules,
config_file,
profile,
Option.value default_target ~default:default_target_default,
List.concat
[ dump_opt "--root" root
; dump_opt "--only-packages" only_packages
; dump_opt "--profile" profile
; dump_opt "--default-target" default_target
; if ignore_promoted_rules then
["--ignore-promoted-rules"]
else
Expand All @@ -534,6 +561,7 @@ let common =
$ ignore_promoted_rules
$ config_file
$ profile
$ default_target
$ frop))
in
let x =
Expand Down Expand Up @@ -680,15 +708,21 @@ let resolve_targets ~log common (setup : Main.setup) user_targets =
let targets =
List.map user_targets ~f:(fun s ->
if String.is_prefix s ~prefix:"@" then begin
let s = String.sub s ~pos:1 ~len:(String.length s - 1) in
let pos, is_rec =
if String.length s >= 2 && s.[1] = '@' then
(2, false)
else
(1, true)
in
let s = String.sub s ~pos ~len:(String.length s - pos) in
let path = Path.relative Path.root (prefix_target common s) in
check_path path;
if Path.is_root path then
die "@@ on the command line must be followed by a valid alias name"
else if not (Path.is_managed path) then
die "@@ on the command line must be followed by a relative path"
else
Ok [Alias_rec path]
Ok [if is_rec then Alias_rec path else Alias path]
end else begin
let path = Path.relative Path.root (prefix_target common s) in
check_path path;
Expand Down Expand Up @@ -725,6 +759,9 @@ let resolve_targets ~log common (setup : Main.setup) user_targets =
List.iter targets ~f:(function
| File path ->
Log.info log @@ "- " ^ (Path.to_string path)
| Alias path ->
Log.info log @@ "- alias " ^
(Path.to_string_maybe_quoted path)
| Alias_rec path ->
Log.info log @@ "- recursive alias " ^
(Path.to_string_maybe_quoted path));
Expand Down Expand Up @@ -756,9 +793,14 @@ let build_targets =
(Main.setup ~log common >>= fun setup ->
let targets = resolve_targets_exn ~log common setup targets in
do_build setup targets) in
let default_target =
match Which_program.t with
| Dune -> "@@default"
| Jbuilder -> "@install"
in
( Term.(const go
$ common
$ Arg.(value & pos_all string ["@install"] name_))
$ Arg.(value & pos_all string [default_target] name_))
, Term.info "build" ~doc ~man)

let runtest =
Expand Down Expand Up @@ -1316,7 +1358,7 @@ let utop =
match resolve_targets_exn ~log common setup [utop_target] with
| [] -> die "no libraries defined in %s" dir
| [File target] -> target
| [Alias_rec _] | _::_::_ -> assert false
| _ -> assert false
in
do_build setup [File target] >>| fun () ->
(setup.build_system, context, Path.to_string target)
Expand Down
2 changes: 2 additions & 0 deletions doc/jbuild.rst
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,8 @@ menhir
A ``menhir`` stanza is available to support the menhir_ parser generator. See
the :ref:`menhir-main` section for details.

.. _alias-stanza:

alias
-----

Expand Down
3 changes: 3 additions & 0 deletions doc/terminology.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Terminology
alias in all children directories recursively. Jbuilder defines the
following standard aliases:

- ``default`` which is the alias build by default when no targets
are specified on the command line. See :ref:`default-alias` for
details
- ``runtest`` which runs user defined tests
- ``install`` which depends on everything that should be installed
- ``doc`` which depends on the generated HTML
Expand Down
40 changes: 37 additions & 3 deletions doc/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ directory as this is normally the case.
Interpretation of targets
=========================

This section describes how ``jbuilder`` interprets the targets given on
the command line.
This section describes how ``dune`` interprets the targets given on
the command line. When no targets are specified, ``dune`` builds the
``default`` alias, see :ref:`default-alias` for more details.

Resolution
----------
Expand Down Expand Up @@ -121,6 +122,38 @@ So for instance:
the ``foo`` build context
- ``jbuilder build @runtest`` will run the tests for all build contexts

You can also build an alias non-recursively by using ``@@`` instead of
``@``. For instance to run tests only from the current directory:

.. code::

dune build @@runtest

.. _default-alias:

Default alias
-------------

When no targets are given to ``dune build``, it builds the special
``default`` alias. Effectively ``dune build`` is equivalent to:

.. code::

dune build @@default

When a directory doesn't explicitly define what the ``default`` alias
means via an :ref:`alias-stanza` stanza, the following implicit
definition is assumed:

.. code::

(alias
(name default)
(deps (alias_rec install)))

Which means that by default ``dune build`` will build everything that
is installable.

Finding external libraries
==========================

Expand Down Expand Up @@ -207,7 +240,7 @@ follows:
build: [["dune" "build" "-p" name "-j" jobs]]

``-p pkg`` is a shorthand for ``--root . --only-packages pkg --profile
release``. ``-p`` is the short version of
release --default-target @install``. ``-p`` is the short version of
``--for-release-of-packages``.

This has the following effects:
Expand All @@ -217,6 +250,7 @@ This has the following effects:
- it sets the root to prevent jbuilder from looking it up
- it sets the build profile to ``release``
- it uses whatever concurrency option opam provides
- it sets the default target to ``@install`` rather than ``@@default``

Note that ``name`` and ``jobs`` are variables expanded by opam. ``name``
expands to the package name and ``jobs`` to the number of jobs available
Expand Down
3 changes: 3 additions & 0 deletions src/build.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Repr = struct
| Fail : fail -> (_, _) t
| Memo : 'a memo -> (unit, 'a) t
| Catch : ('a, 'b) t * (exn -> 'b) -> ('a, 'b) t
| Lazy_no_targets : ('a, 'b) t Lazy.t -> ('a, 'b) t

and 'a memo =
{ name : string
Expand Down Expand Up @@ -132,6 +133,8 @@ let rec all = function
>>>
arr (fun (x, y) -> x :: y)

let lazy_no_targets t = Lazy_no_targets t

let path p = Paths (Path.Set.singleton p)
let paths ps = Paths (Path.Set.of_list ps)
let path_set ps = Paths ps
Expand Down
5 changes: 5 additions & 0 deletions src/build.mli
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ val fanout4 : ('a, 'b) t -> ('a, 'c) t -> ('a, 'd) t -> ('a, 'e) t -> ('a, 'b *

val all : ('a, 'b) t list -> ('a, 'b list) t

(** Optimization to avoiding eagerly computing a [Build.t] value,
assume it contains no targets. *)
val lazy_no_targets : ('a, 'b) t Lazy.t -> ('a, 'b) t

(* CR-someday diml: this API is not great, what about:

{[
Expand Down Expand Up @@ -202,6 +206,7 @@ module Repr : sig
| Fail : fail -> (_, _) t
| Memo : 'a memo -> (unit, 'a) t
| Catch : ('a, 'b) t * (exn -> 'b) -> ('a, 'b) t
| Lazy_no_targets : ('a, 'b) t Lazy.t -> ('a, 'b) t

and 'a memo =
{ name : string
Expand Down
Loading