FAQ

[Clojure] Smarter code reloading with tools.namespace 0.2.0

Stuart Sierra
Oct 5, 2012 at 1:56 pm
Announcing... tools.namespace 0.2.0. Just released, it will reach
Maven Central in a few hours.

Short summary: reload code in the REPL with greater accuracy and
awareness of dependencies.

Full documentation in the README:
https://github.com/clojure/tools.namespace

This is my latest attempt at making REPL development more convenient,
building on work that reaches back to Lazytest and some of my earliest
contribs.

It is hopefully a step towards "Never Close a REPL":
http://dev.clojure.org/display/design/Never+Close+a+REPL

Have fun, let me know how it goes!
-S

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
reply

Search Discussions

11 responses

  • Mayank Jain at Oct 5, 2012 at 10:19 pm
    This will be very helpful to me. Writing selenium tests on repl then
    restarting is a pain. Will share my views on it.

    Thank you for your time :)

    Sent from phone. Please excuse brevity.
    On Oct 5, 2012 7:26 PM, "Stuart Sierra" wrote:

    Announcing... tools.namespace 0.2.0. Just released, it will reach
    Maven Central in a few hours.

    Short summary: reload code in the REPL with greater accuracy and
    awareness of dependencies.

    Full documentation in the README:
    https://github.com/clojure/tools.namespace

    This is my latest attempt at making REPL development more convenient,
    building on work that reaches back to Lazytest and some of my earliest
    contribs.

    It is hopefully a step towards "Never Close a REPL":
    http://dev.clojure.org/display/design/Never+Close+a+REPL

    Have fun, let me know how it goes!
    -S

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with
    your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Mika Raento at Oct 7, 2012 at 11:00 pm
    Hi

    Looks great! I'd just finished writing my own ns declaration parser when I
    found that you'd already put it all together :-)

    What I'd like to use this for is re-running affected tests. A
    straightforward way to make this possible would be to make (refresh) return
    the list of reloaded namespaces. I can submit the code to do this if you
    like the idea. I guess an alternative way would be to add some kind of a
    hook mechanism, but that gets more complex in the case where reloading
    fails.

    (BTW, I submitted a pull request on github to actually use refresh-dirs)

    BR,

    Mika Raento
    On Friday, October 5, 2012 4:56:51 PM UTC+3, Stuart Sierra wrote:

    Announcing... tools.namespace 0.2.0. Just released, it will reach
    Maven Central in a few hours.

    Short summary: reload code in the REPL with greater accuracy and
    awareness of dependencies.

    Full documentation in the README:
    https://github.com/clojure/tools.namespace

    This is my latest attempt at making REPL development more convenient,
    building on work that reaches back to Lazytest and some of my earliest
    contribs.

    It is hopefully a step towards "Never Close a REPL":
    http://dev.clojure.org/display/design/Never+Close+a+REPL

    Have fun, let me know how it goes!
    -S
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Stuart Sierra at Oct 7, 2012 at 11:04 pm
    Hi Mika,

    Due to the current governing process of the Clojure contributor agreement,
    I cannot accept GitHub pull requests, only patches submitted via
    http://dev.clojure.org/jira

    My intent is for the functions in clojure.tools.namespace.repl to be a
    high-level API for direct invocation by users. All the components are
    exposed in the namespaces c.t.n.track, c.t.n.files, etc. You should be able
    to compose the various pieces for different use cases. If you encounter a
    place where this is not possible, let me know and I will look into it.

    -S

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Thomas Heller at Oct 12, 2012 at 3:14 pm
    Hey Stuart,

    I wrote a little "autotest" script which uses tools.namespace to figure out
    which tests to run. Basically I just watch the source files, when modified
    I run (refresh) and use the repl/refresh-tracker var to find out which
    tests should be executed. To do this I had to monkey-patch c.t.n.repl since
    refresh-tracker is private.

    See https://gist.github.com/3865356 Line 6-15.

    Works well enough, but the monkey-patch kinda bothers me, so if you feel
    like adding those functions I'd appreciate it. Maybe they are useful for
    somebody else, since Mika mentioned something similar.

    Anyways, thanks for tools.namespace.

    Regards,
    /thomas
    On Monday, October 8, 2012 1:04:32 AM UTC+2, Stuart Sierra wrote:

    Hi Mika,

    Due to the current governing process of the Clojure contributor agreement,
    I cannot accept GitHub pull requests, only patches submitted via
    http://dev.clojure.org/jira

    My intent is for the functions in clojure.tools.namespace.repl to be a
    high-level API for direct invocation by users. All the components are
    exposed in the namespaces c.t.n.track, c.t.n.files, etc. You should be able
    to compose the various pieces for different use cases. If you encounter a
    place where this is not possible, let me know and I will look into it.

    -S
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Laurent PETIT at Oct 12, 2012 at 4:06 pm
    FWIW, You can access a private var via the var special form: (var
    repl/refresh-tracker) (or #'repl/refresh-tracker for short)

    HTH,

    -- Laurent

    2012/10/10 Thomas Heller <th.heller@gmail.com>
    Hey Stuart,

    I wrote a little "autotest" script which uses tools.namespace to figure
    out which tests to run. Basically I just watch the source files, when
    modified I run (refresh) and use the repl/refresh-tracker var to find out
    which tests should be executed. To do this I had to monkey-patch c.t.n.repl
    since refresh-tracker is private.

    See https://gist.github.com/3865356 Line 6-15.

    Works well enough, but the monkey-patch kinda bothers me, so if you feel
    like adding those functions I'd appreciate it. Maybe they are useful for
    somebody else, since Mika mentioned something similar.

    Anyways, thanks for tools.namespace.

    Regards,
    /thomas
    On Monday, October 8, 2012 1:04:32 AM UTC+2, Stuart Sierra wrote:

    Hi Mika,

    Due to the current governing process of the Clojure contributor
    agreement, I cannot accept GitHub pull requests, only patches submitted via
    http://dev.clojure.org/jira

    My intent is for the functions in clojure.tools.namespace.repl to be a
    high-level API for direct invocation by users. All the components are
    exposed in the namespaces c.t.n.track, c.t.n.files, etc. You should be able
    to compose the various pieces for different use cases. If you encounter a
    place where this is not possible, let me know and I will look into it.

    -S
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with
    your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • James Qiu at Oct 14, 2012 at 9:57 pm
    useful tools

    在 2012年10月5日星期五,Stuart Sierra 写道:
    Announcing... tools.namespace 0.2.0. Just released, it will reach
    Maven Central in a few hours.

    Short summary: reload code in the REPL with greater accuracy and
    awareness of dependencies.

    Full documentation in the README:
    https://github.com/clojure/tools.namespace

    This is my latest attempt at making REPL development more convenient,
    building on work that reaches back to Lazytest and some of my earliest
    contribs.

    It is hopefully a step towards "Never Close a REPL":
    http://dev.clojure.org/display/design/Never+Close+a+REPL

    Have fun, let me know how it goes!
    -S

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com<javascript:;>
    Note that posts from new members are moderated - please be patient with
    your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com <javascript:;>
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Timothy Washington at Oct 15, 2012 at 4:06 am
    I try 2 different repl environments, and run into classpath issues:

    1) *lein.2 repl *

    2) Running emacs with nrepl.el. I fire up "*M-x nrepl-ritz-jack-in*"

    user=> (use '[clojure.tools.namespace.repl :only (refresh)])
    nil

    user=> (refresh)
    :reloading (foojs.core foojs.core-test)
    :error-while-loading foojs.core

    #<FileNotFoundException java.io.FileNotFoundException: Could not
    locate clojure/tools/namespace__init.class or
    *clojure/tools/namespace.clj* on classpath: >


    Now, somewhere in the code, something is looking for
    clojure.tools.namespace.clj. But that's just a directory in the
    project<https://github.com/clojure/tools.namespace/tree/master/src/main/clojure/clojure/tools/namespace>.
    I can't see anywhere in the codebase that tries to use or require that
    file.


    Tim


    On Sat, Oct 13, 2012 at 12:14 AM, James Qiu wrote:

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Stuart Sierra at Oct 16, 2012 at 2:55 pm

    #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/tools/namespace__init.class or *clojure/tools/namespace.clj* on classpath: >


    Now, somewhere in the code, something is looking for
    clojure.tools.namespace.clj. But that's just a directory in the project<https://github.com/clojure/tools.namespace/tree/master/src/main/clojure/clojure/tools/namespace>.
    I can't see anywhere in the codebase that tries to use or require that
    file.
    Something must be trying to load 'clojure.tools.namespace', which was a
    real namespace in the tools.namespace 0.1.x releases. Perhaps something in
    Ritz is trying to load it.

    -S

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Timothy Washington at Oct 16, 2012 at 4:30 pm
    I tracked down the problem. Funny thing is that tools.namespace is failing
    when trying to reload the ring component inside of noir. Looking at *
    nrepl-ritz.el* (0.5.0), which uses *nrepl.el* (0.1.4), there are a few
    references to namespace. But I don't think that has anything to do with
    tools.namespace. So the thing trying to call "clojure.tools.namespace", was
    when the (refresh) stacktrace got to "*ring.middleware.reload*". Below is a
    curated stacktrace.

    nREPL server started on port 42939
    java.io.FileNotFoundException: Could not locate
    clojure/tools/namespace__init.class or clojure/tools/namespace.clj on
    classpath:
    at clojure.lang.RT.load(RT.java:432)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:605)
    at clojure.core$use.doInvoke(core.clj:5392)
    at clojure.lang.RestFn.invoke(RestFn.java:482)
    at
    ns_tracker.core$eval2801$loading__4784__auto____2802.invoke(core.clj:1)
    at ns_tracker.core$eval2801.invoke(core.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    ...
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    *at
    ring.middleware.reload$eval2795$loading__4784__auto____2796.invoke(reload.clj:1)
    *
    * at ring.middleware.reload$eval2795.invoke(reload.clj:1)*
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    ...
    at clojure.lang.RestFn.invoke(RestFn.java:457)
    *at
    noir.server.handler$eval2789$loading__4784__auto____2790.invoke(handler.clj:1)
    *
    * at noir.server.handler$eval2789.invoke(handler.clj:1)*
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    ...
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    *at
    noir.server$eval2145$loading__4784__auto____2146.invoke(server.clj:1)*
    * at noir.server$eval2145.invoke(server.clj:1)*
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    ...
    *at
    clojure.tools.namespace.reload$track_reload_one.invoke(reload.clj:35)*
    * at
    clojure.tools.namespace.reload$track_reload.invoke(reload.clj:52)*
    ...
    *at
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:42)
    *
    * at
    clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__536$fn__538.invoke(interruptible_eval.clj:170)
    *
    at clojure.core$comp$fn__4034.invoke(core.clj:2278)
    at
    clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__529.invoke(interruptible_eval.clj:137)
    at clojure.lang.AFn.run(AFn.java:24)
    at
    java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)


    Digging through ring code is another kettle of fish. Does ring need to be
    updated? If so, tools.namespace will have to deal would these issues on a
    library by library basis.


    Thanks
    Tim



    On Tue, Oct 16, 2012 at 9:11 AM, Stuart Sierra
    wrote:
    #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/tools/namespace__init.**class or *clojure/tools/namespace.clj* on classpath: >

    Now, somewhere in the code, something is looking for
    clojure.tools.namespace.clj. But that's just a directory in the project<https://github.com/clojure/tools.namespace/tree/master/src/main/clojure/clojure/tools/namespace>.
    I can't see anywhere in the codebase that tries to use or require that
    file.
    Something must be trying to load 'clojure.tools.namespace', which was a
    real namespace in the tools.namespace 0.1.x releases. Perhaps something in
    Ritz is trying to load it.

    -S
    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Stuart Sierra at Oct 16, 2012 at 7:40 pm
    'ring-devel' depends on 'ns-tracker', which uses tools.namespace 0.1.3:
    https://github.com/weavejester/ns-tracker/blob/master/project.clj

    Dependency resolution will only allow one version of the library, so your
    project gets tools.namespace 0.2.0, not 0.1.3. The two releases are not
    compatible, which is documented in the README.

    This will have to be fixed in ring-devel and/or ns-tracker.

    -S

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en
  • Hugo Duncan at Oct 16, 2012 at 7:55 pm

    Timothy Washington writes:

    2) Running emacs with nrepl.el. I fire up "*M-x nrepl-ritz-jack-in*"
    ritz-repl-utils includes a namespace dependency graph in
    ritz.repl-utils.namespaces. It doesn't yet include a refresh type
    function, but that would be straightforward to add on top of a call to
    `(transitive-dependencies (direct-dependencies))`.

    Hugo

    --
    You received this message because you are subscribed to the Google
    Groups "Clojure" group.
    To post to this group, send email to clojure@googlegroups.com
    Note that posts from new members are moderated - please be patient with your first post.
    To unsubscribe from this group, send email to
    clojure+unsubscribe@googlegroups.com
    For more options, visit this group at
    http://groups.google.com/group/clojure?hl=en

Related Discussions