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

Gracefully handle Git deletions again #137

Merged
merged 17 commits into from
Mar 2, 2020
Merged

Gracefully handle Git deletions again #137

merged 17 commits into from
Mar 2, 2020

Conversation

vemv
Copy link
Contributor

@vemv vemv commented Feb 27, 2020

Brief

impl/absolutize, particularly with its .exists assertion, had broken our ability to gracefully handle deleted files (staged or not).

This PR fixes that, adding an extensive integration test.

QA plan

Test all cases in a real project (suggestion: a monorepo):

  • Deleted file (staged for deletion or not)
  • plain core/format!, format-and-lint-project!, format-and-lint-branch!

That's 6 scenarios - please let's test them all (I have in formatting-stack itself).

Author checklist

  • I have QAed the functionality
  • The PR has a reasonably reviewable size and a meaningful commit history
  • I have run the branch formatter and observed no new/significative warnings
  • The build passes
  • I have self-reviewed the PR prior to assignment
  • Additionally, I have code-reviewed iteratively the PR considering the following aspects in isolation:
    • Correctness
    • Robustness (red paths, failure handling etc)
    • Modular design
    • Test coverage
    • Spec coverage
    • Documentation
    • Security
    • Performance
      • defn all-files peforms 3 git ops but they're fairly cheap (5-15ms each)
    • Breaking API changes
    • Cross-compatibility (Clojure/ClojureScript)

Reviewer checklist

  • I have checked out this branch and reviewed it locally, running it
  • I have QAed the functionality
  • I have reviewed the PR
  • Additionally, I have code-reviewed iteratively the PR considering the following aspects in isolation:
    • Correctness
    • Robustness (red paths, failure handling etc)
    • Modular design
    • Test coverage
    • Spec coverage
    • Documentation
    • Security
    • Performance
    • Breaking API changes
    • Cross-compatibility (Clojure/ClojureScript)

@vemv vemv changed the base branch from master to cljs-old--v2 February 28, 2020 03:41
@vemv vemv marked this pull request as ready for review February 28, 2020 03:54
@vemv vemv requested a review from thumbnail February 28, 2020 03:54
@vemv vemv changed the title [WIP] Gracefully handle Git deletions again Gracefully handle Git deletions again Feb 28, 2020
Copy link
Member

@thumbnail thumbnail left a comment

Choose a reason for hiding this comment

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

Good work 👍 extensive tests as well :)

Comment on lines +14 to +18

(assert (-> deletable-file .exists))

(assert (not (-> createable-filename File. .exists)))

Copy link
Member

Choose a reason for hiding this comment

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

These should be inside of the test. The files don't have to exist/not-exists when loading this ns, they should when i run the tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These should be inside of the test.

Note that 2 deftests depend on this assertion. Having 2 deftests fail seems less clear, concise and immediate than having (refresh) fail as soon as an issue arises.

Copy link
Member

Choose a reason for hiding this comment

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

Except that now i can refresh, delete the file and run the test. yielding unclear failures as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Except that now i can refresh, delete the file and run the test.

Running tests without a prior (refresh) seems just wrong. Our dev.clj file typically suggests to (refresh) prior to running any test

@vemv vemv changed the base branch from cljs-old--v2 to master February 28, 2020 09:31
@vemv
Copy link
Contributor Author

vemv commented Feb 28, 2020

Ready again!

Copy link
Member

@thumbnail thumbnail left a comment

Choose a reason for hiding this comment

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

during QA i noticed that absolutize might not work as expected in monorepos:

The module part is missing from the path. (e.g. project-dir/src is used instead of project-dir/module/src)

@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

👀!

Did you get exceptions? Supposedly there's a spec that would assert impl/absolutize output would correspond to an existing file

@thumbnail
Copy link
Member

Supposedly there's a spec that would assert impl/absolutize output would correspond to an existing file

It's probably happening when *skip-existing-files-check?* is bound to true

@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

Did you get exceptions?

(For clarity: at least the spec checking part was working, w/ nice Expound reports)

@thumbnail
Copy link
Member

Did you get exceptions?

Only the ExceptionInfo-exceptions with the validation errors.

-- Relevant specs -------

:formatting-stack.strategies.impl/existing-files:
  (clojure.spec.alpha/coll-of
   (nedap.speced.def/fn
    [s]
    (if
     formatting-stack.strategies.impl/*skip-existing-files-check?*
     true
     (clojure.core/-> s File. .exists))))

-- Spec failed --------------------

  (...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   "<SNIP>"
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...
   ...)

should satisfy

  (speced/fn
   [s]
   (if *skip-existing-files-check?* true (-> s File. .exists)))

-- Relevant specs -------

:formatting-stack.strategies.impl/existing-files:
  (clojure.spec.alpha/coll-of
   (nedap.speced.def/fn
    [s]
    (if
     formatting-stack.strategies.impl/*skip-existing-files-check?*
     true
     (clojure.core/-> s File. .exists))))

-------------------------
Detected 27 errors

Execution error (ExceptionInfo) at formatting-stack.strategies/all-files$fn (strategies.clj:47).
Validation failed

@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

Some notes:

  • git status porcelain always emits paths relative to the git root, not to the cwd
  • git diff --name-status always emits paths relative to the git root, not to the cwd
  • git ls-files, at least by default emits paths relative to the cwd

The latter, beng different, is a source of issues.

This makes `ls-files` option more analog to that of `diff --name-status` and `status --porcelain`, in that it is independent from the current directory (which is relevant for monorepos)
@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

Kindly QA again. I'll be also, over a non-monorepo

@thumbnail
Copy link
Member

staged/unstaged deleted files within the same module work as expected. However strategies/all-files only returns the files present in (System/getProperty "user.dir") (e.g. the module itself). Not the files outside of the module.

@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

I thought about that.

It seems bit of a poor default to return files outside of the monorepo. Most folks will not want files outside of the current project to be returned.

Else they will be formatting/linting files outside of what Clojure can require, so bugs would arise.

That's a non-issue for us with the :monorepo profile, or people doing similar stuff (https://clubhouse.io/blog/monolith-meet-mono-repo/). But it seems unsafe to assume that everyone will have that set up.

(Even among us :monorepo is optional)

@thumbnail
Copy link
Member

Else they will be formatting/linting files outside of what Clojure can require, so bugs would arise.

This is not necessarily true, the files might be on the classpath, but not in the current project. It might be specific to our monorepo setup, but running project-formatter/format-and-lint-project! for each project could make sense 🤔

@vemv
Copy link
Contributor Author

vemv commented Mar 2, 2020

This is not necessarily true, the files might be on the classpath, but not in the current project.

Yes, but we cannot know with all certainty.

(Monorepo != "all projects can reach each other's set of namespaces")

Created #139 + #140 btw, which can be attended promptly but would not consider a blocker (as f-s is somewhat broken rn)

@vemv vemv merged commit c1455b6 into master Mar 2, 2020
@vemv vemv mentioned this pull request Mar 2, 2020
7 tasks
@thumbnail thumbnail deleted the deleted branch March 2, 2020 16:32
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.

2 participants