day8 / re-com

A ClojureScript library of reusable components for Reagent
https://re-com.day8.com.au
MIT License
796 stars 147 forks source link

Create Script to Modify Sources with :src Annotations #258

Closed superstructor closed 3 years ago

superstructor commented 3 years ago

In the latest re-com release we added support for annotating components with the source code coordinates via the :src parameter and (at) macro; see https://re-com.day8.com.au/#/debug

This requires that re-com users add :src (at) to as much as their re-com code as possible; e.g.:

(ns my-app.views
  (:require
    [re-com.core :as rc :refer [at]] ;; <- here
    [reagent.core :as r]
    ...))

(defn my-view
   []
   [rc/v-box
      :src (at) ;; <- here
      :children [[rc/title
                         :src (at) ;; <- here
                         ...]
                      ...]
      ...]

Write a script using rewrite-cljs to transform source via zippers while maintaining comments and white-space/formatting. This will be a 'run once' script that modifies the files in a directory (e.g. src/) in your project repository that you can then inspect and commit the changes to source control using your normal tools.

Run the script via babashka if you can get it to load rewrite-cljs, otherwise via lein-exec. Either way, place this in a new directory under the re-com project root named scripts/; e.g. for lein-exec it could look like:

scripts/
scripts/at-macro/project.clj
scripts/at-macro/README.md
scripts/at-macro/src/
scripts/at-macro/test
...

At outline of what the script should ultimately do is:

  1. Given a directory 'src-dir'
  2. Walk the entire tree of directories and files under 'src-dir' finding all *.cljs files
  3. Read the file
  4. Inspect the (ns ... form looking for [re-com.core ... in (:requires ...
  5. If re-com is not found, stop processing that file and move on.
  6. If re-com is found,
    • Add the (at) macro to [re-com.core :refer [at]
    • go through all s-exprs in that file looking for vectors
  7. If a vector does not start with a re-com component; e.g. [rc/vbox ... stop processing that vector and move on to the next vector. Note you'll need to resolve the full namespace of rc/vbox to re-com.core/v-box and the equality check should be against the full ns re-com.core/v-box NOT the alias. Also, excludes re-com.core/p components as p is the only component that does not support :src.
  8. Check if the vector already has a :src parameter, if so stop processing that vector and move on to the next vector.
  9. Write the vector to include :src (at)
  10. After processing all sexprs/vectors, write the file back out to disk.

Resources