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

Consistent resolution of project root w.r.t --project-file path #7749

Closed

Conversation

pranaysashank
Copy link

@pranaysashank pranaysashank commented Oct 14, 2021

  • This commit sets the ProjectRoot consistently for both absolute
    and relative --project-file paths. The ProjectRoot is set as the
    directory where the --project-file is located.

  • Before this change relative project files are rooted to where the
    project file is resolved, when recursively searching upward from
    the current directory, and not where it is located.

    Previous behaviour is as follows. With the following directory layout:

  gitpod ~/0/1/2/foo $ tree ~/0
  /home/gitpod/0
  └── 1
      ├── 2
      │   └── foo
      │       ├── app
      │       │   └── Main.hs
      │       ├── CHANGELOG.md
      │       └── foo.cabal
      └── cabal.project

and inside foo let's run

  $ pwd
  /home/gitpod/0/1/2/foo
  $ cabal build all --project-file ../cabal.project

which builds the project setting the project root at 2 using
the project file at 1

  $ ls ~/0/1 ~/0/1/2
  /home/gitpod/0/1:
  2  cabal.project

  /home/gitpod/0/1/2:
  dist-newstyle foo

However, if the cabal.project file was instead in 0 directory,
cabal would fail to build since the resolved project root is at
1 and cabal fails to find a package at 1/foo

  gitpod ~/0/1/2/foo $ mv ~/0/1/cabal.project ~/0/
  gitpod ~/0/1/2/foo $ cabal build all --project-file ../cabal.project
  When using configuration(s) from /home/gitpod/0/1/../cabal.project, the following errors occurred:
  The package location 'foo' does not exist.

This behaviour is almost never what we want.

See #7695

Please include the following checklist in your PR:

Please also shortly describe how you tested your change. Bonus points for added tests!

@Mikolaj Mikolaj requested a review from fgaz October 15, 2021 06:56
@fgaz
Copy link
Member

fgaz commented Nov 9, 2021

Could you add a changelog entry? It'd be nice to have a test too, but I'm not sure if that's doable with the current test infrastructure

@pranaysashank
Copy link
Author

I see some tests that directly use findProjectRoot function. I think we can probably write an additional test for it.

@pranaysashank
Copy link
Author

Just an update: the fix above has a bug & is wrong when startDir is passed to findProjectRoot. (Looks like this argument is used only in the testing code and nowhere else.)

@Mikolaj
Copy link
Member

Mikolaj commented Nov 29, 2021

Yes, seems to be used only for tests.

@Mikolaj
Copy link
Member

Mikolaj commented Jan 29, 2022

@pranaysashank: hi! how is it going?

@pranaysashank
Copy link
Author

Hi, I didn't get time to come back to this and it completely slipped off my radar. The PR works except in tests where the argument startDir is used, perhaps we can change current directory some other way in the tests and remove the startDir argument completely?

@Mikolaj
Copy link
Member

Mikolaj commented Jan 31, 2022

perhaps we can change current directory some other way in the tests and remove the startDir argument completely?

Sure, why not. I'm sure there are explicit ways of changing directory available.

- This commit sets the ProjectRoot consistently for both absolute
  and relative --project-file pats. The ProjectRoot is set as the
  directory where the --project-file is located.
- Before this change relative project files are rooted to where the
  project file is resolved, when recursively searching upward from
  the current directory, and not where it is located.

  Previous behaviour is as follows,

  gitpod ~/0/1/2/foo $ tree ~/0
  /home/gitpod/0
  └── 1
      ├── 2
      │   └── foo
      │       ├── app
      │       │   └── Main.hs
      │       ├── CHANGELOG.md
      │       └── foo.cabal
      └── cabal.project

  and inside foo let's run

  $ pwd
  /home/gitpod/0/1/2/foo
  $ cabal build all --project-file ../cabal.project

  which builds the project setting the project root at 2 using
  the project file at 1

  $ ls ~/0/1 ~/0/1/2
  /home/gitpod/0/1:
  2  cabal.project

  /home/gitpod/0/1/2:
  dist-newstyle foo

  However, if the cabal.project file was instead in 0 directory,
  cabal would fail to build since the resolved project root is at
  1 and cabal fails to find a package at 1/foo

  gitpod ~/0/1/2/foo $ mv ~/0/1/cabal.project ~/0/
  gitpod ~/0/1/2/foo $ cabal build all --project-file ../cabal.project
  When using configuration(s) from /home/gitpod/0/1/../cabal.project, the following errors occurred:
  The package location 'foo' does not exist.

  This beaviour is almost never what we want.
- It's not used anywhere other than in tests and complicates
 implementation.
@pranaysashank
Copy link
Author

The tests are failing because it couldn't find the directory, likely because we are running the tests from the outer directory. So, this works

cabal test integration-tests2 --test-option '-p' --test-option 'find root'

but not

cabal run integration-tests2 -- -p 'find root'

Is there a way to change directory in the tests correctly in both the scenarios?

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

Wow, I had no idea one can even do

 cabal run integration-tests2

Perhaps let's just switch this to cabal test everywhere in CI scripts? Does either of

$(cabal list-bin integration-tests2) -- -p 'find root'

or

$(cabal list-bin exe:integration-tests2) -- -p 'find root'

or

`cabal list-bin test:integration-tests2` -- -p 'find root'

work fine?

@pranaysashank
Copy link
Author

No none of those work, I need to be in cabal-install directory for any of them to work. I guess cabal test puts me in the correct working directory somehow.

In the same IntegrationTests2 file, there is also a function configureProject which calls cleanProject testdir (defined in the same file). I wonder how and if it works.

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

Actually, the CI script I had in mind changes to that directory:

.github/workflows/windows.yml-          cd cabal-install
.github/workflows/windows.yml:          cabal v2-run cabal-install:integration-tests2

it's the other one that doesn't:

validate.sh:CMD="$($CABALPLANLISTBIN cabal-install:test:integration-tests2) -j1 --hide-successes --with-ghc=$HC"

Would it work to just slip cd cabal-install; before the $($CABALPLANLISTBIN?

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

And you may be right that cleanProject is wrong if not called from cabal-install/, because it uses the hardwired

basedir = "tests" </> "IntegrationTests2"

and I wasn't able to find there calls to any code that goes up the directory hierarchy to find the real project root. I might have missed something, though. Anyway, if cleanProject is wrong then it's one more reason to only call the tests from cabal-install/.

@pranaysashank
Copy link
Author

pranaysashank commented Apr 8, 2022

Would it work to just slip cd cabal-install; before the $($CABALPLANLISTBIN?

Yep, that should work

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

Or one could try something like

validate.sh:CMD="$CABAL test cabal-install:test:integration-tests2 --test-options='-j1 --hide-successes --with-ghc=$HC'"

though I'm not sure in what order to next the quotes, etc.

@pranaysashank
Copy link
Author

yes although --test-options usually doesn't work for me with patterns, that's why I used test-option twice and passed the flags individually in my comment above

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

Yes, I have the same problem. Would that be a bug or do we lack some obvious shell trick to make it work?

@pranaysashank
Copy link
Author

Would that be a bug or do we lack some obvious shell trick to make it work?

It's a bug in splitArgs function; I figured a way to make it work which is double quotes inside single quotes and not the other way around,
so this works

cabal test integration-tests2 --test-options '-p "find root"'

but not this

cabal test integration-tests2 --test-options "-p 'find root'"

because,

> splitArgs "-p 'find root'"
["-p","'find","root'"]

--test-options is annoying for another reason which is that every time you change them, cabal re-configures the packages in the project.

@Mikolaj
Copy link
Member

Mikolaj commented Apr 8, 2022

Yay, great findings. Could you file both issues? If not, I will do that, because they are important usability hiccups and both seem reasonably easily fixable.

@pranaysashank
Copy link
Author

pranaysashank commented Apr 8, 2022

I'll file them (See #8090, #8091)

@mergify mergify bot added the merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days label Sep 1, 2022
@ulysses4ever ulysses4ever removed the merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days label Sep 3, 2022
@cydparser cydparser mentioned this pull request Sep 5, 2022
3 tasks
@cydparser
Copy link
Collaborator

I've created a PR that moves towards consistency in a different way here: #8454.

@Mikolaj
Copy link
Member

Mikolaj commented Oct 17, 2022

Could I ask for help reviewing the PR fixing this issue (#8454)? Even a cursory look and a comment whether this might fix your use case (bonus points for checking out and confirming) would be very much appreciated.

@pranaysashank
Copy link
Author

pranaysashank commented Oct 17, 2022

@Mikolaj From reading the description and comments in that PR, it doesn't look like it's related to this issue / PR. This PR fixes the project resolution when the project file is passed as a relative path. The open question listed in the --project-dir PR (#8454) is what this PR fixes but the issue is a bit more complicated than child directory being the project root (as mentioned in the open question), the main issue was what I wrote in the second point in description of this PR

Before this change relative project files are rooted to where the
project file is resolved, when recursively searching upward from
the current directory, and not where it is located.

I haven't checked if this behaviour was fixed in a recent release / HEAD. This PR gives the same behaviour desired in the open question i.e. with this fix --project-file ../cabal.project will be equivalent to --project-dir ../

@Mikolaj
Copy link
Member

Mikolaj commented Oct 17, 2022

@pranaysashank: my bad, I assumed this is one of the issues potentially fixed by #8454, while this is a PR fixing a related issue. Thank you for you remarks, though.

@Mikolaj
Copy link
Member

Mikolaj commented Nov 23, 2022

A new proposal dropped at #8454. Could you kindly voice your opinion?

@ulysses4ever
Copy link
Collaborator

A new proposal dropped at #8454. Could you kindly voice your opinion?

#8454 has been merged. I wonder if this PR may be closed now as superseded by that one.

@Kleidukos
Copy link
Member

@pranaysashank shall we close this PR? :)

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

Successfully merging this pull request may close these issues.

6 participants