Giter VIP home page Giter VIP logo

lein-nsorg's Introduction

lein-nsorg

Leiningen plugin for organizing ns form in a way that whitespace and comments are preserved.

Rules to apply are fully customizable; the default implementation

  • sorts :require, :require-macros, :use and :use-macros libspecs alphabetically and removes duplicates
  • sorts :import class names alphabetically and removes duplicates
  • sorts :exclude, :only, :refer, :refer-macros and :rename options alphabetically and removes duplicates

Also available as Clojure library nsorg and command line tool nsorg-cli.

Installation

Dependency information:

[lein-nsorg "0.3.0"]

Usage

lein nsorg

Example output:

...
in ./src/perf/clojure/clojure/java/perf_jdbc.clj:
   These test compare the raw performance (against an in-memory H2 database)
   for hand-crafted Java JDBC calls and various `query` and `reducible-query`
   calls."
-  (:require [criterium.core :as cc]
-            [clojure.java.jdbc :as sql])
-  (:import (java.sql Connection PreparedStatement ResultSet Statement ResultSetMetaData)))
+  (:require [clojure.java.jdbc :as sql]
+            [criterium.core :as cc])
+  (:import (java.sql Connection PreparedStatement ResultSet ResultSetMetaData Statement)))

 (defn calibrate []
   ;; 840ms
...

Checked 5 files, found problems in 3 files

Paths

Paths to check can be given as arguments to the plugin:

lein nsorg src dev/src

If no locations are given default location is:

  • :source-paths and :test-paths if plugin is run inside Leiningen project
  • current directory if plugin is run outside Leiningen project

Ignoring files

You can ignore a specific file or directory by excluding it from command-line:

lein nsorg --exclude src/my-project/broken_file.clj --exclude test

Apply changes automatically

By default lein-nsorg prints diffs for suggested changes. Changes can be applied automatically to source files with the following option:

lein nsorg --replace

Interactive mode

Instead of applying changes automatically interactive mode asks for each file if suggestions should be applied or not:

lein nsorg --replace --interactive

License

Copyright © 2018 Immo Heikkinen

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

lein-nsorg's People

Contributors

immoh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lein-nsorg's Issues

Getting `java.lang.UnsupportedOperationException: null`

Hi @immoh and thanks for this feature!
I just followed the installation, so i added the plugin to my .lein/profiles.clj and run lein nsrog with this project https://github.com/akvo/akvo-lumen

but getting java.lang.UnsupportedOperationException: null

Checking following paths:
dev/src
src
test

in dev/src/dev.clj:
             [clojure.tools.namespace.repl :refer [refresh]]
             [com.stuartsierra.component :as component]
             [duct.generate :as gen]
-            [duct.util.repl :refer [setup test cljs-repl] :as duct-repl]
+            [duct.util.repl :refer [cljs-repl setup test] :as duct-repl]
             [duct.util.system :refer [load-system]]
-            [reloaded.repl :refer [system init start stop go reset]])
-  (:import [org.postgresql.util PSQLException PGobject]))
+            [reloaded.repl :refer [go init reset start stop system]])
+  (:import [org.postgresql.util PGobject PSQLException]))

 (defn new-system []
   (load-system (keep io/resource

in src/akvo/lumen/admin/bootstrap.clj:
 (ns akvo.lumen.admin.bootstrap
-  (:require [clojure.java.jdbc :as jdbc]
-            [clojure.string :as s]
-            [environ.core :refer [env]]
-            [akvo.lumen.admin.util :as util]
-            [akvo.lumen.util :refer [squuid]]
+  (:require [akvo.lumen.admin.util :as util]
+            [akvo.lumen.util :refer [squuid]]
+            [clojure.java.jdbc :as jdbc]
+            [clojure.string :as s]
+            [environ.core :refer [env]]
             [ragtime.jdbc]
             [ragtime.repl]))


in src/akvo/lumen/boundary/error_tracker.clj:
   (:require [akvo.lumen.component.error-tracker]
             [raven-clj.core :as raven]
             [raven-clj.interfaces :as raven-interface])
-  (:import [akvo.lumen.component.error_tracker SentryErrorTracker LocalErrorTracker]))
+  (:import [akvo.lumen.component.error_tracker LocalErrorTracker SentryErrorTracker]))

 (defprotocol IErrorTracker
   (track [this error]))

in src/akvo/lumen/endpoint/dashboard.clj:
 (ns akvo.lumen.endpoint.dashboard
-  (:require [compojure.core :refer :all]
-            [akvo.lumen.component.tenant-manager :refer [connection]]
-            [akvo.lumen.lib.dashboard :as dashboard]))
+  (:require [akvo.lumen.component.tenant-manager :refer [connection]]
+            [akvo.lumen.lib.dashboard :as dashboard]
+            [compojure.core :refer :all]))


 (defn endpoint [{:keys [tenant-manager]}]

in src/akvo/lumen/endpoint/healthz.clj:
 (ns akvo.lumen.endpoint.healthz
   (:require [akvo.lumen.http :as http]
-            [environ.core :as env]
-            [compojure.core :refer :all]))
+            [compojure.core :refer :all]
+            [environ.core :as env]))

 (defn endpoint [_]
   (GET "/healthz" {:as req}

in src/akvo/lumen/endpoint/job_execution.clj:
 (ns akvo.lumen.endpoint.job-execution
-  (:require [compojure.core :refer :all]
-            [akvo.lumen.component.tenant-manager :refer [connection]]
-            [akvo.lumen.lib.job-execution :as job-execution]))
+  (:require [akvo.lumen.component.tenant-manager :refer [connection]]
+            [akvo.lumen.lib.job-execution :as job-execution]
+            [compojure.core :refer :all]))


 (defn endpoint [{:keys [tenant-manager]}]

in src/akvo/lumen/endpoint/library.clj:
   (:require [akvo.lumen.component.tenant-manager :refer [connection]]
             [akvo.lumen.lib :as lib]
             [akvo.lumen.lib
-             [dashboard :as dashboard]
-             [dataset :as dataset]
-             [visualisation :as visualisation]
-             [collection :as collection]
-             [raster :as raster]]
+             [collection :as collection]
+             [dashboard :as dashboard]
+             [dataset :as dataset]
+             [raster :as raster]
+             [visualisation :as visualisation]]
             [akvo.lumen.variant :as variant]
             [compojure.core :refer :all]))


in src/akvo/lumen/endpoint/share.clj:
 (ns akvo.lumen.endpoint.share
-  (:require [compojure.core :refer :all]
-            [akvo.lumen.component.tenant-manager :refer [connection]]
-            [akvo.lumen.lib.share :as share]))
+  (:require [akvo.lumen.component.tenant-manager :refer [connection]]
+            [akvo.lumen.lib.share :as share]
+            [compojure.core :refer :all]))


 (defn endpoint [{:keys [tenant-manager]}]

in src/akvo/lumen/import.clj:
              [clojure.string :as string]
              [clojure.tools.logging :as log]
              [hugsql.core :as hugsql])
-  (:import [org.postgis Polygon MultiPolygon]
+  (:import [org.postgis MultiPolygon Polygon]
            [org.postgresql.util PGobject]))

 (hugsql/def-db-fns "akvo/lumen/job-execution.sql")

in src/akvo/lumen/lib/aes.clj:
 (ns akvo.lumen.lib.aes
   (:import [java.security SecureRandom]
            [javax.crypto Cipher]
-           [javax.crypto.spec SecretKeySpec IvParameterSpec]
+           [javax.crypto.spec IvParameterSpec SecretKeySpec]
            [org.apache.commons.codec.binary Base64]
            [org.apache.commons.codec.digest DigestUtils]))


in src/akvo/lumen/lib/collection_impl.clj:
             [clojure.java.jdbc :as jdbc]
             [clojure.set :as set]
             [hugsql.core :as hugsql])
-  (:import [java.sql SQLException Connection]))
+  (:import [java.sql Connection SQLException]))

 (alias 'core 'clojure.core)


in src/akvo/lumen/migrate.clj:
    [hugsql.core :as hugsql]
    [meta-merge.core :refer [meta-merge]]
    [ragtime
-    strategy
-    [jdbc :as ragtime-jdbc]
-    [repl :as ragtime-repl]]))
+    [jdbc :as ragtime-jdbc]
+    [repl :as ragtime-repl]
+    strategy]))

 (hugsql/def-db-fns "akvo/lumen/migrate.sql")


in src/akvo/lumen/transformation/derive.clj:
             [clojure.string :as str]
             [clojure.tools.logging :as log]
             [hugsql.core :as hugsql])
-  (:import [javax.script ScriptEngineManager ScriptEngine Invocable ScriptContext Bindings]
-           [jdk.nashorn.api.scripting NashornScriptEngineFactory ClassFilter]))
+  (:import [javax.script Bindings Invocable ScriptContext ScriptEngine ScriptEngineManager]
+           [jdk.nashorn.api.scripting ClassFilter NashornScriptEngineFactory]))

 (hugsql/def-db-fns "akvo/lumen/transformation/derive.sql")
 (hugsql/def-db-fns "akvo/lumen/transformation/engine.sql")

in src/akvo/lumen/transformation/merge_datasets.clj:
 (ns akvo.lumen.transformation.merge-datasets
-  (:require [akvo.lumen.transformation.engine :as engine]
-            [akvo.lumen.import.common :as import]
+  (:require [akvo.lumen.import.common :as import]
+            [akvo.lumen.transformation.engine :as engine]
             [clojure.java.jdbc :as jdbc]
             [clojure.set :as set]
             [clojure.string :as s]

in test/akvo/lumen/auth_test.clj:
 (ns akvo.lumen.auth-test
   (:require [akvo.lumen.auth :as m]
-            [clojure.test :refer [deftest testing is]]
+            [clojure.test :refer [deftest is testing]]
             [ring.mock.request :as mock]))

 (defn- test-handler

in test/akvo/lumen/component/tenant_manager_test.clj:
 (ns akvo.lumen.component.tenant-manager-test
-  (:require [clojure.test :refer :all]
-            [akvo.lumen.component.tenant-manager :as tenant-manager]))
+  (:require [akvo.lumen.component.tenant-manager :as tenant-manager]
+            [clojure.test :refer :all]))

 (deftest hostname->tenant
   (are [host expected-tenant] (= expected-tenant (tenant-manager/tenant-host host))

in test/akvo/lumen/endpoint/collection_test.clj:
 (ns akvo.lumen.endpoint.collection-test
   {:functional true}
-  (:require [akvo.lumen.fixtures :refer [*tenant-conn*
-                                         tenant-conn-fixture
-                                         *error-tracker*
-                                         error-tracker-fixture]]
+  (:require [akvo.lumen.fixtures :refer [*error-tracker*
+                                         *tenant-conn*
+                                         error-tracker-fixture
+                                         tenant-conn-fixture]]
             [akvo.lumen.lib :as lib]
             [akvo.lumen.lib.collection :as collection]
             [akvo.lumen.lib.dashboard :as dashboard]

java.lang.UnsupportedOperationException: null
 at rewrite_clj.node.uneval.UnevalNode.sexpr (uneval.clj:6)
    rewrite_clj.zip.base$sexpr.invokeStatic (base.clj:49)
    rewrite_clj.zip.base$sexpr.invoke (base.clj:46)
    nsorg.core$sort_map_option$fn__4407.invoke (core.clj:12)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:33)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk_subtree.invokeStatic (walk.clj:32)
    rewrite_clj.zip.walk$postwalk_subtree.invoke (walk.clj:27)
    rewrite_clj.zip.walk$postwalk$fn__4057.invoke (walk.clj:43)
    rewrite_clj.zip.subedit$subedit_node.invokeStatic (subedit.clj:69)
    rewrite_clj.zip.subedit$subedit_node.invoke (subedit.clj:65)
    rewrite_clj.zip.walk$postwalk.invokeStatic (walk.clj:43)
    rewrite_clj.zip.walk$postwalk.invoke (walk.clj:37)
    nsorg.zip$organize_ns_form$fn__4398.invoke (zip.clj:78)
    clojure.lang.PersistentVector.reduce (PersistentVector.java:341)
    clojure.core$reduce.invokeStatic (core.clj:6544)
    clojure.core$reduce.invoke (core.clj:6527)
    nsorg.zip$organize_ns_form.invokeStatic (zip.clj:76)
    nsorg.zip$organize_ns_form.invoke (zip.clj:65)
    nsorg.core$rewrite_ns_form.invokeStatic (core.clj:85)
    nsorg.core$rewrite_ns_form.invoke (core.clj:73)
    nsorg.core$rewrite_ns_form.invokeStatic (core.clj:82)
    nsorg.core$rewrite_ns_form.invoke (core.clj:73)
    leiningen.nsorg$organize_ns_forms_BANG_.invokeStatic (nsorg.clj:53)
    leiningen.nsorg$organize_ns_forms_BANG_.invoke (nsorg.clj:48)
    leiningen.nsorg$nsorg.invokeStatic (nsorg.clj:94)
    leiningen.nsorg$nsorg.doInvoke (nsorg.clj:75)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.Var.invoke (Var.java:379)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$partial_task$fn__4667.doInvoke (main.clj:284)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$apply_task.invokeStatic (main.clj:334)
    leiningen.core.main$apply_task.invoke (main.clj:320)
    lein_environ.plugin$write_env_to_file.invokeStatic (plugin.clj:18)
    lein_environ.plugin$write_env_to_file.invoke (plugin.clj:16)
    clojure.lang.Var.invoke (Var.java:394)
    clojure.lang.AFn.applyToHelper (AFn.java:165)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    robert.hooke$compose_hooks$fn__9113.doInvoke (hooke.clj:40)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    robert.hooke$run_hooks.invokeStatic (hooke.clj:46)
    robert.hooke$run_hooks.invoke (hooke.clj:45)
    robert.hooke$prepare_for_hooks$fn__9118$fn__9119.doInvoke (hooke.clj:54)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:340)
    leiningen.core.main$resolve_and_apply.invoke (main.clj:336)
    leiningen.core.main$_main$fn__4734.invoke (main.clj:420)
    leiningen.core.main$_main.invokeStatic (main.clj:411)
    leiningen.core.main$_main.doInvoke (main.clj:408)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.lang.Var.invoke (Var.java:379)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.main$main_opt.invokeStatic (main.clj:314)
    clojure.main$main_opt.invoke (main.clj:310)
    clojure.main$main.invokeStatic (main.clj:421)
    clojure.main$main.doInvoke (main.clj:384)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.main.main (main.java:37)

Static useless import removal?

Hi! Thanks for this project, it's a nice tool to keep code clean. What would it take to remove unused or duplicate imports? Could this be done statically?

Throwing error when unmatched delimiter

I have lein-nsorg running all the time, along with cljfmt.
If I accidentally save source code with invalid format, i.e. unmatched delimiter, the nsorg task will crash and stop my lein JVM. cljfmt will just show a message: Failed to format file: src/foo/bar.cljs.

Maybe it would be good to have the same behavior as cljfmt in nsorg, to make it suitable to run in a long-running process with lein-auto and lein-cooper?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.