-
Notifications
You must be signed in to change notification settings - Fork 70
Introduce wrap-ignore-errors
#317
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
Conversation
I'm strongly opposed to footguns like this (and all our other When the user turns on M-x yolo-mode we have no way of distinguishing between actual errors and errors that they want us to DWIM and ignore. If they have one or more errors in their project that prevents actual analysis and then run
In a perfect world everyone would be doing red, green, refactor, but that's not how the majority of us works. I for one will very often be working on X and then go off on a tangent to refactor something. If my work on X was incomplete to the point where clj-refactor can't reliable execute my requested refactoring I NEVER want it to just YOLO on. That will turn a 5 second tangent into a huge detour that will drop me out of my state of flow completely. As far as #291 goes I believe a much better solution would be to let this op too take into account the edit: man, this brings back memories. Benedek and I went so many rounds on |
Why don’t you use with-safe-transport instead? That’s auto-handled in CIDER
and is the way to go in all middle IMO. I planned to push this helper to
nREPL itself at some point, but never got to doing so.
…On Sat, 3 Jul 2021 at 23:30, Lars Andersen ***@***.***> wrote:
I'm strongly opposed to footguns like this.
When the user turns on M-x yolo-mode they have no way of distinguishing
between actual errors and errors that they want us to DWIM and ignore.
If they have one or more errors in their project that prevents actual
analysis and then run cljr-rename-symbol we'll do a half-finished job and
their only recourse (because we don't have an undo for this operation) is:
- Git reset --hard HEAD
- Manually finishing / undoing the job
In a perfect world everyone would be doing red, green, refactor, but
that's not how the majority of us works. I for one will very often be
working on X and then go off on a tangent to refactor something. If my work
on X was incomplete to the point where clj-refactor can't reliable execute
my requested refactoring I NEVER want it to just YOLO on. That will turn a
5 second tangent into a huge detour that will drop me out of my state of
flow completely.
As far as #291
<#291> goes I
believe a much better solution would be to let this op too take into
account the ignore-paths config setting that let's the user tell us about
e.g. their template files.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#317 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAZLSTILX4LHZMNE3TCRNLTV56ODANCNFSM47YGA6HA>
.
|
Thanks for bringing it up. I don't think it tackles exactly the same problem: with-safe-transport informs of exceptions, while this PR allows functionality to work. ...I'm aware that an end user, after being informed by with-safe-transport of a stacktrace, could fix the corresponding root cause, retry the op and get it to work. But I think that for a very significant array of use cases, things should work OOTB. I'll write up a refined proposal following @expez' remarks which are certainly useful! |
Fair enough. I’m without a computer for a few days so it’s hard to
elaborate my point, but in general I agree with him. And in general I
believe that generic functionality should live somewhere higher up the
stack, so it’s available to more tools/clients.
On Sun, 4 Jul 2021 at 20:04, vemv ***@***.***> wrote:
Why don’t you use with-safe-transport instead?
Thanks for bringing it up. I don't think it tackles exactly the same
problem: with-safe-transport informs of exceptions, while this PR allows
functionality to *work*.
...I'm aware that an end user, after being informed by with-safe-transport
of a stacktrace, could fix the corresponding root cause, retry the op and
get it to work.
But I think that for a very significant array of use cases, things should
work OOTB. I'll write up a refined proposal following @expez
<https://github.com/expez>' remarks which are certainly useful!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#317 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAZLSST52ZVCMIJ7K7MBT3TWCPC3ANCNFSM47YGA6HA>
.
--
Best Regards,
Bozhidar Batsov
|
In the context of My reasoning behind suppressing errors is that we're hijacking the |
Firstly, it's worth emphasizing the focus of this PR: it ignores errors while building a corpus (namely: reading/requiring files, and sometimes building an AST out of them). It does not propose wrapping the operations themselves (e.g. Building a corpus is somewhat prone to errors whenever the whole project (i.e. not just :source-paths/:test-paths) is being analysed. Which can quite plausibly happen in face of the following considerations:
So, long story short, it's more than plausible that refactor-nrepl can choke on irrelevant files. I don't think that not working (sometimes opaquely) is a good behavior. Even if refactor-nrepl did accurately inform of the problematic file, asking people to configure their project feels pedantic and may not succeed. One can argue, people want things to 'just work', not a tool give to them more problems :) especially for the mentioned use cases: newcomers, people who work with a lot of projects, or people who prioritize other things over spending time with fine-grained tooling settings. Anyway, I don't think that the segment of the user base that actually configures things carefully should pay any price for this leniency. So based on @expez input I thought of... strict-modestrict-mode would simply a boolean option. Its value would translate directly to the The interesting part being, strict-mode would be set dynamically following the following rules/heuristics:
WDYT? Between the limited scope of the changes (corpus building) and optionality/smartness of a strict-mode option, this could be a net win in terms of user experience. |
As one last note, sometimes ASTs can't be built purely becase tools.analyzer errors (bugs). e.g. core.async stuff. But one can make a sensible (although not risk-free) bet: the code that made t.ana choke was irrelevant for the op in question (e.g. it wouldn't be renamed at all by Right now, The result might be slightly invalid, but the user could either fix that manually or discard the results altogether. I don't think that's too much of an ask: no IDE's "rename" is perfect so a seasoned user will have some cautions around automated refactoring (e.g. git-commit prior work, run tests before committing, etc) |
This is probably the one hill I'd be willing to die on when it comes to this project. The setting that allows
FWIW, we're not bundled along with CIDER. @benedekfazekas did an amazing job of porting the refactorings that don't require the middleware (e.g.
I guess this is the gist of my disagreement about
Many Clojure projects will have at least one Emacs enthusiast and they will add a
This line of reasoning is great, because I think we have a lot of ways to sidestep reliability problems related to
In a previous life I wrote enterprise Java code and I can't recall experiencing Intellij making mistakes on a regular basis. If I ever saw that I would upgrade to the latest version and/or file a bug report. Teaching people to alter their workflow to accommodate the tool is IMO undesirable to begin with but also about as hard as teaching them to configure their tool correctly (which they only have to do once). |
Yeah, I don't have any objections to this PR. We already have I realize I sent us off on a bit of tangent, and I apologize for that, but this line:
really triggered me 🤣 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on this! 👍
src/refactor_nrepl/ns/tracker.clj
Outdated
@@ -36,13 +37,16 @@ | |||
;; corner case - use the mranderson-ized refresh-dirs (for supporting this project's test suite): | |||
refresh-dirs)) | |||
|
|||
(def default-predicate (every-pred core/source-file? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default-file-predicate
or maybe even something like filter-file-predicate
? The latter gives some indication that we're using this predicate to filter the files to be processed.
src/refactor_nrepl/util.clj
Outdated
(f x) | ||
(catch Exception e | ||
(maybe-log-exception e) | ||
;; return false, because `wrap-ignore-errors` is oriented for predicate usage: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the trailing :
in this comment makes it seem like something is missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the trailing : in this comment makes it seem like something is missing
I add the colon to make it clear that the comment refers to the next LOC. Else there can be an ambiguity (does it refer to the previous one, to the defn in general, etc?)
I guess it failed at that 😇
src/refactor_nrepl/ns/libspecs.clj
Outdated
aliases-by-frequencies)}) | ||
([] | ||
(namespace-aliases false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra line here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will rm it
(fwiw it was there on purpose... I don't like "shim" arities to clutter the "impl" arity, so that I can read the impl better)
src/refactor_nrepl/ns/tracker.clj
Outdated
(defn project-files-in-topo-order | ||
([] | ||
(project-files-in-topo-order false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra blank line here
|
||
([old-path new-path] | ||
(rename-file-or-dir old-path new-path false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra line here
src/refactor_nrepl/ns/libspecs.clj
Outdated
sym-by-file&fullname)}) | ||
([] | ||
(referred-syms-by-file&fullname false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra line here
CHANGELOG.md
Outdated
@@ -2,6 +2,18 @@ | |||
|
|||
## Unreleased | |||
|
|||
#### Changes | |||
* The `:ignore-errors` option will be honored in more places, making refactor-nrepl more robust in face of files not particularly meant to be part of the AST corpus. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also document this more prominently somewhere, as there are a couple of other editors using refactor-nrepl
.
CHANGELOG.md
Outdated
#### Changes | ||
* The `:ignore-errors` option will be honored in more places, making refactor-nrepl more robust in face of files not particularly meant to be part of the AST corpus. | ||
* Examples: WIP files, Moustache template files, scripts. | ||
* Closes https://github.com/clojure-emacs/refactor-nrepl/issues/291 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a prefix of the parent CL entry.
CHANGELOG.md
Outdated
* Upgrade Orchard | ||
* Worth emphasizing: now the following options are available https://github.com/clojure-emacs/orchard/tree/v0.7.0#configuration-options | ||
* They can make the refactor-nrepl experience simpler / more robust. | ||
* Reliabilty improvement: try using `require` prior to `find-ns` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a typo in reliability
@@ -0,0 +1,29 @@ | |||
(ns refactor-nrepl.unreadable-files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also add some ns comment about the purpose of the file.
src/refactor_nrepl/util.clj
Outdated
@@ -72,3 +72,14 @@ | |||
(defn maybe-log-exception [^Throwable e] | |||
(when (System/getProperty "refactor-nrepl.internal.log-exceptions") | |||
(.printStackTrace e))) | |||
|
|||
(defn wrap-ignore-errors [f ignore-errors?] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A docstring is in order for everything part of the public API.
I've got one concern with the |
For completeness, I was referring to this passage of the readme:
I appreciate this thinking and most definitely wouldn't want to bend the project to accomodate "everyone". But perhaps by appealing only to an "elite" persona we'd unnecessarily lose many people's trust (by giving a perceived-buggy experience by default, as argued before). It's not the same to target 40% of devs than 5%. 5% is too little an can end up being counterproductive. Anyway thanks for the willingness 🤝 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@expez , would you want something like "strict-mode" added to this PR?
Personally I'd actually like it since I wouldn't want gratuitous swallowing either
src/refactor_nrepl/ns/libspecs.clj
Outdated
aliases-by-frequencies)}) | ||
([] | ||
(namespace-aliases false)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will rm it
(fwiw it was there on purpose... I don't like "shim" arities to clutter the "impl" arity, so that I can read the impl better)
src/refactor_nrepl/util.clj
Outdated
(f x) | ||
(catch Exception e | ||
(maybe-log-exception e) | ||
;; return false, because `wrap-ignore-errors` is oriented for predicate usage: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the trailing : in this comment makes it seem like something is missing
I add the colon to make it clear that the comment refers to the next LOC. Else there can be an ambiguity (does it refer to the previous one, to the defn in general, etc?)
I guess it failed at that 😇
Not really, this PR already contains quite a bit of code and tons of discussion. I also don't like the idea of This probably goes without saying but |
Yeah always sounds good to seek agreement in advance 👍
Ok cheers 🍻 likewise I'd much care about the other maintainer being happy with our creation :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR ready again, will squash the new commit as the last step
(defn- rename-file-or-dir-reply [{:keys [transport old-path new-path] :as msg}] | ||
(reply transport msg :touched (@rename-file-or-dir old-path new-path) | ||
(defn- rename-file-or-dir-reply [{:keys [transport old-path new-path ignore-errors] :as msg}] | ||
(reply transport msg :touched (@rename-file-or-dir old-path new-path (= ignore-errors "true")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I should compare against true
or "true"
here?
...Checking out the codebase, I see a handful of "true"
handlings. But there's also a boolean coercion in config.clj which makes me hesitate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct, the stuff that's in the msg
hasn't yet been coerced to boolean.
I suppose we could've done a better job of consistently doing coercions in this ns (like you're doing now) instead of passing the msg
on as is.
@vemv Did you see this remark? |
Addessed now. Had left it for later as it escaped my eye at first. Thanks for the feedback both, hope this is, as foreseen, a net gain. Anyway I'll create an issue trying to refine the "strict-mode" idea (might have to be more fine-grained) |
Fixes #291
Interestingly, merely by adding intentionally-invalid .clj files to
test-resources
, all sorts of tests/functionality in the codebase started to break. This surfaced thatwrap-ignore-errors
is pretty necessary, as otherwise it doesn't seem ideal that the occasional odd file in the source path will render refactor-nrepl useless.This is particularly true for end users that may have not explicitly set the paths to be analyzed (i.e. they may trying to analyze a whole project, not just a subset like
src
/test
).The README already advises to set :ignore-errors, so now with this improvement that's more true than ever.