File in invalid path will mark namespace for reload

Description

Having a cljc file at path public/js/out/foo/bar.cljc with ns form (ns foo.bar) will result in namespace foo.bar being reloaded.

This is problematic because ClojureScript compiler will copy all the input files to :output-dir for source-map use. Lately as more libraries have started using cljc, and this has started causing problems in cases where library is used on Clojure env. Cljs compilation will result in reload of the library code, which can redefine protocols etc. and break the Clojure env.

I think it would make sense for tools.namespace to ignore changes where file path and namespace don't match.
Another question and perhaps way to fix this, is to understand why dependency resolution doesn't work in this case: namespaces which depend on the protocols at a cljc file on output-dir aren't reloaded.

Environment

None

Activity

Show:
Juho Teperi
January 1, 2018, 12:42 PM

-5 patch modifies find-files to check ignored directories if all the ns declarations in the directory have been fixed. I had to move the side-effects from predicate functions to find-files so this is not the cleanest change, but should work. I should be able to clean this a bit if this seems like good approach.

Juho Teperi
January 1, 2018, 12:40 PM

Great!

I applied and installed this locally and tested with one Boot projects where I know Cljs output contains some [[.cljc}} namespaces, and this indeed ignores those.

Two notes:

Every time I call refresh, I get the warning about directory being ignored. This does add a bit clutter, but is probably acceptable, as system restart will probably log a few lines anyway in most cases.

One thing that might be a problematic, is that if single file has bad ns declaration at some point, e.g. user accidentally has typo on the name, the whole directory is ignored untill clear is called. This will probably cause confusion. Would it make sense automatically remove ignored directories if the problematic files are fixed? Looks like that would be possible in find-files.

Stuart Sierra
January 1, 2018, 12:36 AM

Using c.t.n.repl, an ignored directory can be added back to the scan by calling c.t.n.repl/clear to initialize a new tracker.

Stuart Sierra
January 1, 2018, 12:34 AM

New patch file TNS-45-4.patch prints a warning and adds the ignored directories to the tracker, following suggestions in comment by Dominic Monroe.

This applies only to c.t.n.dir/scan-dirs, so other uses of the lower-level APIs in tools.namespace should not be affected.

On the first occurrence of a file not matching scan-dirs will print a warning will print a warning to err with the the declared ns name and the path to the file that did not match. After that, the entire directory will be ignored, and a notification will be printed on each invocation of scan-dirs. I hope this strikes a good balance between informative messages and not too many spurious warnings.

Note: previous patch file TNS-42-3.patch was mis-named but was always meant to apply to TNS-45.

Dominic Monroe
November 13, 2017, 1:12 PM

Discarded files/namespaces could be added to the tracker, to mitigate confusion. Refresh could then warn about those files with `prn` as it does now.

Something would need to remove files from the discarded list if they ever became valid.

I'm not sure this should block TNS-45, but could be something for someone to pick up as follow-up.

Your pinned fields
Click on the next to a field label to start pinning.

Assignee

Stuart Sierra

Reporter

Juho Teperi

Patch

Code and Test