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

Initialize new project in current directory #9209

Closed
Ajlow2000 opened this issue Nov 17, 2023 · 10 comments · Fixed by #9447 or ocaml/opam-repository#25081
Closed

Initialize new project in current directory #9209

Ajlow2000 opened this issue Nov 17, 2023 · 10 comments · Fixed by #9447 or ocaml/opam-repository#25081

Comments

@Ajlow2000
Copy link

Desired Behavior

I would like to be able to run dune init proj NAME and have it create my project in place (ie, not a subdirectory ./NAME).

Current Behavior / Problem Space

Currently dune init proj NAME requires a NAME parameter and creates a subdirectory. Every time I've used dune to initialize a project, I am starting from an empty git repo, and running dune from the repo's root. This creates the dune project nested down a level which I don't want. I work around this by moving the contents of the newly created subdirectory up to the repo's root, and then deleting the now empty ./NAME directory that was created by dune. This is uncomfortable for someone who's new to the language and is spinning up new projects that are very small in scope just to learn (ie: me).

Example

Intended functionality would be similar to nix flake initi.
Example workflow for initializing project:

# Create a new bare repo on github.com
git clone my/repo
nix flake init # included to show how I expected dune to work
dune init proj MY_PROJ --in-place
# write some ocaml

Initial Considerations

My initial intuition when using dune was just to run dune init proj (omitting the name parameter) as this is how other tooling like nix flake init works. Because the name parameter gets used for more then just the path in which to create the dune project, my suggestion is to add an optional flag that specifies that I want my dune project created in-place. Something like --in-place is narrow in scope and behavior, or --path=/my/custom/path which could give more flexibility to the tool at the cost of intuitiveness.

@nojb
Copy link
Collaborator

nojb commented Nov 17, 2023

+1 for this suggestion; I also found the NAME behaviour unintuitive. The suggestion matches the behaviour of git, for example (where git init initializes a repository the current directory).

@yawaramin
Copy link
Contributor

Another idea: dune init proj . which should work similarly to git init . i.e. initialize the component using the name of the current directory.

@nojb
Copy link
Collaborator

nojb commented Nov 17, 2023

Another idea: dune init proj . which should work similarly to git init . i.e. initialize the component using the name of the current directory.

Sounds like a good idea to me.

@Ajlow2000
Copy link
Author

Worth noting how cargo does this: https://doc.rust-lang.org/cargo/commands/cargo-init.html#examples

Create a binary Cargo package in the current directory:
cargo init

I havent dug into src, but I imagine it uses the current directory as the project name. I like the explicitness of @yawaramin suggestion though.

@Ajlow2000
Copy link
Author

Another idea: dune init proj . which should work similarly to git init . i.e. initialize the component using the name of the current directory.

Thought: Dashes (-) in filenames are perfectly valid, but currently get rejected from dune init proj NAME. Combine that with the fact that best practices with naming git repos using dashes over underscores (my understanding is this is due to readability in urls), and things get a bit convoluted. I suppose this case doesn't necessary need handled as it might be out scope, but it warrants a comment at least.

@shonfeder
Copy link
Collaborator

Here's the commands help currently:

NAME
       dune-init - Command group for initializing dune components

SYNOPSIS
       dune init proj NAME [PATH] [OPTION]...
       dune init exec NAME [PATH] [OPTION]...
       dune init lib NAME [PATH] [OPTION]...
       dune init test NAME [PATH] [OPTION]...

DESCRIPTION
       dune init COMPONENT NAME [PATH] [OPTION]... initializes a new dune
       configuration for a component of the kind specified by the subcommand
       COMPONENT, named NAME, with fields determined by the supplied OPTIONs.

       Run a subcommand with  --help for for details on it's supported
       arguments

       If the optional PATH is provided, the component will be created there.
       Otherwise, it is created in the current working directory.

Using the optional PATH argument currently works like this:

$ dune init proj myproj foo/bar/baz
Entering directory '$PWD/foo/bar/baz/myproj'
Success: initialized project component named myproj

Making the first positional argument sometimes act like a project name and sometimes be inferred as a directory would conflict with this behavior. This is in addition to the conflict @Ajlow2000 notes with naming constraints. There is also possible ambiguity if a directory of the same name were present when you meant to just supply a name. Given these complications, I think @yawaramin's suggestion may be impracticable.

cargo init makes sense in the context of cargo because they also have cargo new (I initially wanted project template creation to be under a new subcommand, following this example. See, e.g., #159 (comment)).

I like @Ajlow2000's suggestion of --in-place, but will also propose these possible options:

  1. At the price of a tiny breaking change, we can change the behavior of the optional PATH argument so that it work as @Ajlow2000 suggested for the --path flag. Currently, we add a new directory at the end of the given PATH, but this makes dune init proj foo . equivalent to dune init proj foo. Instead, if a path is given, we can create the assents in the named directory. This is arguably more intuitive.
  2. At the price of a bigger breaking change, we can rework the CLI to use new and init subcommands, adopting the idiom used by cargo (and poetry).

I like the idea of (1) ok, actually. WDYT?

@yawaramin
Copy link
Contributor

I tried out (1) and actually I think there is a small discrepancy between how the two variants should behave based on common sense understanding:

dune init proj foo .

This creates a new project in a subdirectory foo.

dune init proj foo foo

This creates a new project in a subdirectory foo.

The second behaviour makes sense. But then, in those terms, the first behaviour does not make sense. If we specify a path foo and dune creates a subdirectory foo, then it should not also create a subdirectory if we specify the current directory ..

I think this should be changed so that the first command should create the project in place in the current directory.

@shonfeder
Copy link
Collaborator

shonfeder commented Nov 18, 2023

Good find! Given that inconsistency, I think it is arguable that the current behavior is erroneous. We can implement (1) as a bug fix, and add a line to the docs noting how to initialize a project in the current directory.

Any objections, concerns, or better ideas?

@Alizter
Copy link
Collaborator

Alizter commented Nov 18, 2023

I personally think its ok to change the behaviour of dune init in a non-backwards-compatible way if it means new users have a better experience. I think its probably worth discussing in the next Dune meeting however.

@shonfeder
Copy link
Collaborator

I'd support that, @Alizter. We have a lot of feedback to draw from, as well as other mature tools we can take inspiration from at this point.

Following up on @Ajlow2000's point about cargo behavior, it does indeed infer the name from the parent dir, and just raises in error if is invalid:

$ cd '=__--*'/
$ cargo init
error: invalid character `=` in crate name: `=__--*`, the first character must be a Unicode XID start character (most letters or `_`)
use --name to override crate name

cargo new also doesn't differentiate between a path and the package name:

$ cargo new foo/bar/baz
     Created binary (application) `foo/bar/baz` package
$ rg name foo/bar/baz/Cargo.toml
2:name = "baz"

It addresses the ambiguity I was concerned with by just signaling an error if a directory already exists with the same name as intended project.

@shonfeder shonfeder self-assigned this Dec 10, 2023
shonfeder added a commit to shonfeder/dune that referenced this issue Dec 10, 2023
Fixes ocaml#9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
shonfeder added a commit to shonfeder/dune that referenced this issue Dec 10, 2023
Fixes ocaml#9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
shonfeder added a commit to shonfeder/dune that referenced this issue Dec 10, 2023
Fixes ocaml#9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
shonfeder added a commit to shonfeder/dune that referenced this issue Dec 11, 2023
Fixes ocaml#9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
shonfeder added a commit to shonfeder/dune that referenced this issue Dec 16, 2023
Fixes ocaml#9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
rgrinberg pushed a commit that referenced this issue Jan 2, 2024
…9447)

Fixes #9209

Signed-off-by: Shon Feder <shon.feder@gmail.com>
emillon added a commit to emillon/opam-repository that referenced this issue Jan 12, 2024
CHANGES:

- Do not ignore `(formatting ..)` settings in context or workspace files
  (ocaml/dune#8447, @rgrinberg)

- Add command `dune cache clear` to completely delete all traces of the Dune
  cache. (ocaml/dune#8975, @nojb)

- Fixed a bug where Dune was incorrectly parsing the output of coqdep when it
  was escaped, as is the case on Windows. (ocaml/dune#9231, fixes ocaml/dune#9218, @Alizter)

- Copying mode for sandboxes will now follow symbolic links (ocaml/dune#9282, @rgrinberg)

- Forbid the empty `(binaries ..)` field in the `env` stanza in the workspace
  file unless language version is at least 3.2.

- [coq] Fix bug in computation of flags when composed with boot theories.
  (ocaml/dune#9347, fixes ocaml/dune#7909, @ejgallego)

- Fixed a bug where the `(select)` field of the `(libraries)` field of the
  `(test)` stanza wasn't working properly. (ocaml/dune#9387, fixes ocaml/dune#9365, @Alizter)

- Allow to disable Coq 0.8 deprecation warning (ocaml/dune#9439, @ejgallego)

- Fix handling of the `PATH` argument to `dune init proj NAME PATH`. An
  intermediate directory called `NAME` is no longer created if `PATH` is
  supplied, so `dune init proj my_project .` will now initialize a project in
  the current working directory. (ocaml/dune#9447, fixes ocaml/dune#9209, @shonfeder)

- Allow `OCAMLFIND_TOOLCHAIN` to be set per context in the workspace file
  through the `env` stanza. (ocaml/dune#9449, @rgrinberg)

- Experimental doc rules: Correctly handle the case when a package depends upon
  its own sublibraries (ocaml/dune#9461, fixes ocaml/dune#9456, @jonludlam)

- Resolve various public binaries to their build location, rather than to where
  they're copied in the `_build/install` directory (ocaml/dune#9496, fixes ocaml/dune#7908,
  @rgrinberg).

- Menhir: generate `.conflicts` file by default. Add new field to the
  `(menhir)` stanza to control the generation of this file: `(explain <blang
  expression>)`. Introduce `(menhir (flags ...) (explain ...))` field in the
  `(env)` stanza, delete `(menhir_flags)` field. All changes are guarded under
  a new version of the Menhir extension, 3.0. (ocaml/dune#9512, @nojb)

- Correctly ignore warning flags in vendored projects (ocaml/dune#9515, @rgrinberg)

- Directory targets can now be caches. (ocaml/dune#9535, @rleshchinskiy)

- Remove warning 30 from default set for projects where dune lang is at least
  3.13 (ocaml/dune#9568, @gasche)

- It is now possible to use special forms such as `(:include)` and variables
  `%{read-lines:}` in `(modules)` and similar fields. Note that the
  dependencies introduced in this way (ie the files being read) must live in a
  different directory than the stanza making use of them. (ocaml/dune#9578, @nojb)

- Use watch exclusions in watch mode on MacOS (ocaml/dune#9643, fixes ocaml/dune#9517,
  @PoorlyDefinedBehaviour)

- Fix merlin configuration for `(include_subdirs qualified)` modules (ocaml/dune#9659,
  fixes ocaml/dune#8297, @rgrinberg)

- Fix handling of `enabled_if` in binary install stanzas. Previously, we'd
  ignore the result of `enabled_if` when evaluating `%{bin:..}` (ocaml/dune#9707,
  @rgrinberg)

- Add `coqdoc_flags` field to `coq` field of `env` stanza allowing the setting
  of workspace-wide defaults for `coqdoc_flags`. (ocaml/dune#9280, fixes ocaml/dune#9139, @Alizter)

- ctypes: fix an error where `(ctypes)` with no `(function_description)` would
  cause an error trying refer to a nonexistent `_stubs.a` dependency (ocaml/dune#9302,
  fix ocaml/dune#9300, @emillon)
emillon added a commit to emillon/opam-repository that referenced this issue Jan 16, 2024
CHANGES:

### Added

- Add command `dune cache clear` to completely delete all traces of the Dune
  cache. (ocaml/dune#8975, @nojb)

- Allow to disable Coq 0.8 deprecation warning (ocaml/dune#9439, @ejgallego)

- Allow `OCAMLFIND_TOOLCHAIN` to be set per context in the workspace file
  through the `env` stanza. (ocaml/dune#9449, @rgrinberg)

- Menhir: generate `.conflicts` file by default. Add new field to the
  `(menhir)` stanza to control the generation of this file: `(explain <blang
  expression>)`. Introduce `(menhir (flags ...) (explain ...))` field in the
  `(env)` stanza, delete `(menhir_flags)` field. All changes are guarded under
  a new version of the Menhir extension, 3.0. (ocaml/dune#9512, @nojb)

- Directory targets can now be cached. (ocaml/dune#9535, @rleshchinskiy)

- It is now possible to use special forms such as `(:include)` and variables
  `%{read-lines:}` in `(modules)` and similar fields. Note that the
  dependencies introduced in this way (ie the files being read) must live in a
  different directory than the stanza making use of them. (ocaml/dune#9578, @nojb)

- Remove warning 30 from default set for projects where dune lang is at least
  3.13 (ocaml/dune#9568, @gasche)

- Add `coqdoc_flags` field to `coq` field of `env` stanza allowing the setting
  of workspace-wide defaults for `coqdoc_flags`. (ocaml/dune#9280, fixes ocaml/dune#9139, @Alizter)

- ctypes: fix an error where `(ctypes)` with no `(function_description)` would
  cause an error trying refer to a nonexistent `_stubs.a` dependency (ocaml/dune#9302,
  fix ocaml/dune#9300, @emillon)

### Changed

- Check that package names in `(depends)` and related fields in `dune-project`
  are well-formed. (ocaml/dune#9472, fixes ocaml/dune#9270, @ElectreAAS)

### Fixed

- Do not ignore `(formatting ..)` settings in context or workspace files
  (ocaml/dune#8447, @rgrinberg)

- Fixed a bug where Dune was incorrectly parsing the output of coqdep when it
  was escaped, as is the case on Windows. (ocaml/dune#9231, fixes ocaml/dune#9218, @Alizter)

- Copying mode for sandboxes will now follow symbolic links (ocaml/dune#9282, @rgrinberg)

- Forbid the empty `(binaries ..)` field in the `env` stanza in the workspace
  file unless language version is at least 3.2.

- [coq] Fix bug in computation of flags when composed with boot theories.
  (ocaml/dune#9347, fixes ocaml/dune#7909, @ejgallego)

- Fixed a bug where the `(select)` field of the `(libraries)` field of the
  `(test)` stanza wasn't working properly. (ocaml/dune#9387, fixes ocaml/dune#9365, @Alizter)

- Fix handling of the `PATH` argument to `dune init proj NAME PATH`. An
  intermediate directory called `NAME` is no longer created if `PATH` is
  supplied, so `dune init proj my_project .` will now initialize a project in
  the current working directory. (ocaml/dune#9447, fixes ocaml/dune#9209, @shonfeder)

- Experimental doc rules: Correctly handle the case when a package depends upon
  its own sublibraries (ocaml/dune#9461, fixes ocaml/dune#9456, @jonludlam)

- Resolve various public binaries to their build location, rather than to where
  they're copied in the `_build/install` directory (ocaml/dune#9496, fixes ocaml/dune#7908,
  @rgrinberg).

- Correctly ignore warning flags in vendored projects (ocaml/dune#9515, @rgrinberg)

- Use watch exclusions in watch mode on MacOS (ocaml/dune#9643, fixes ocaml/dune#9517,
  @PoorlyDefinedBehaviour)

- Fix merlin configuration for `(include_subdirs qualified)` modules (ocaml/dune#9659,
  fixes ocaml/dune#8297, @rgrinberg)

- Fix handling of `enabled_if` in binary install stanzas. Previously, we'd
  ignore the result of `enabled_if` when evaluating `%{bin:..}` (ocaml/dune#9707,
  @rgrinberg)
nberth pushed a commit to nberth/opam-repository that referenced this issue Jun 18, 2024
CHANGES:

### Added

- Add command `dune cache clear` to completely delete all traces of the Dune
  cache. (ocaml/dune#8975, @nojb)

- Allow to disable Coq 0.8 deprecation warning (ocaml/dune#9439, @ejgallego)

- Allow `OCAMLFIND_TOOLCHAIN` to be set per context in the workspace file
  through the `env` stanza. (ocaml/dune#9449, @rgrinberg)

- Menhir: generate `.conflicts` file by default. Add new field to the
  `(menhir)` stanza to control the generation of this file: `(explain <blang
  expression>)`. Introduce `(menhir (flags ...) (explain ...))` field in the
  `(env)` stanza, delete `(menhir_flags)` field. All changes are guarded under
  a new version of the Menhir extension, 3.0. (ocaml/dune#9512, @nojb)

- Directory targets can now be cached. (ocaml/dune#9535, @rleshchinskiy)

- It is now possible to use special forms such as `(:include)` and variables
  `%{read-lines:}` in `(modules)` and similar fields. Note that the
  dependencies introduced in this way (ie the files being read) must live in a
  different directory than the stanza making use of them. (ocaml/dune#9578, @nojb)

- Remove warning 30 from default set for projects where dune lang is at least
  3.13 (ocaml/dune#9568, @gasche)

- Add `coqdoc_flags` field to `coq` field of `env` stanza allowing the setting
  of workspace-wide defaults for `coqdoc_flags`. (ocaml/dune#9280, fixes ocaml/dune#9139, @Alizter)

- ctypes: fix an error where `(ctypes)` with no `(function_description)` would
  cause an error trying refer to a nonexistent `_stubs.a` dependency (ocaml/dune#9302,
  fix ocaml/dune#9300, @emillon)

### Changed

- Check that package names in `(depends)` and related fields in `dune-project`
  are well-formed. (ocaml/dune#9472, fixes ocaml/dune#9270, @ElectreAAS)

### Fixed

- Do not ignore `(formatting ..)` settings in context or workspace files
  (ocaml/dune#8447, @rgrinberg)

- Fixed a bug where Dune was incorrectly parsing the output of coqdep when it
  was escaped, as is the case on Windows. (ocaml/dune#9231, fixes ocaml/dune#9218, @Alizter)

- Copying mode for sandboxes will now follow symbolic links (ocaml/dune#9282, @rgrinberg)

- Forbid the empty `(binaries ..)` field in the `env` stanza in the workspace
  file unless language version is at least 3.2.

- [coq] Fix bug in computation of flags when composed with boot theories.
  (ocaml/dune#9347, fixes ocaml/dune#7909, @ejgallego)

- Fixed a bug where the `(select)` field of the `(libraries)` field of the
  `(test)` stanza wasn't working properly. (ocaml/dune#9387, fixes ocaml/dune#9365, @Alizter)

- Fix handling of the `PATH` argument to `dune init proj NAME PATH`. An
  intermediate directory called `NAME` is no longer created if `PATH` is
  supplied, so `dune init proj my_project .` will now initialize a project in
  the current working directory. (ocaml/dune#9447, fixes ocaml/dune#9209, @shonfeder)

- Experimental doc rules: Correctly handle the case when a package depends upon
  its own sublibraries (ocaml/dune#9461, fixes ocaml/dune#9456, @jonludlam)

- Resolve various public binaries to their build location, rather than to where
  they're copied in the `_build/install` directory (ocaml/dune#9496, fixes ocaml/dune#7908,
  @rgrinberg).

- Correctly ignore warning flags in vendored projects (ocaml/dune#9515, @rgrinberg)

- Use watch exclusions in watch mode on MacOS (ocaml/dune#9643, fixes ocaml/dune#9517,
  @PoorlyDefinedBehaviour)

- Fix merlin configuration for `(include_subdirs qualified)` modules (ocaml/dune#9659,
  fixes ocaml/dune#8297, @rgrinberg)

- Fix handling of `enabled_if` in binary install stanzas. Previously, we'd
  ignore the result of `enabled_if` when evaluating `%{bin:..}` (ocaml/dune#9707,
  @rgrinberg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment