From 6644e1596f81870d596a43e12d72732cf28c992f Mon Sep 17 00:00:00 2001 From: Metaxal Date: Sat, 31 Jul 2021 16:17:05 +0100 Subject: [PATCH 1/4] Improve command line parsing and help displaying previously: $ racket -l- resyntax does nothing, leaving the user unsure what to do. After some code/doc search, the user may try $ racket -l- resyntax/cli but this again does nothing $racket -l- resyntax/cli --help say either "analyze" or "fix" should be used $racket -l- resyntax/cli analyze does again nothing $racket -l- resyntax/cli analyze --help finally provides some useful guidance. new behaviour: $ racket -l- resyntax displays a message to try the following: $ racket -l- resyntax/cli --help Furthermore, all of $ racket -l- resyntax/cli $ racket -l- resyntax/cli --analyze $ racket -l- resyntax/cli --fix default to adding the "--help" flag so as to provide meaningful help. Command line parsing has been changed to look more like hierarchical argument parsing. A `parameterize-help-if-empty-ccla` form makes the command line arguments default to #("--help") if they are empty. The "analyze" and "fix" commands are now parsed properly by `command-line`, which means they must be written "--analyze" and "--fix". --- cli.rkt | 123 +++++++++++++++++++++++++++++++---------------------- main.rkt | 3 ++ main.scrbl | 22 +++++----- 3 files changed, 85 insertions(+), 63 deletions(-) diff --git a/cli.rkt b/cli.rkt index ba232c98..5b6081e5 100644 --- a/cli.rkt +++ b/cli.rkt @@ -7,6 +7,7 @@ racket/match racket/path racket/string + racket/vector rebellion/base/option rebellion/collection/entry rebellion/collection/hash @@ -21,7 +22,8 @@ resyntax/file-group resyntax/refactoring-result resyntax/refactoring-suite - resyntax/source) + resyntax/source + syntax/parse/define) ;@---------------------------------------------------------------------------------------------------- @@ -30,31 +32,43 @@ (define-record-type resyntax-options (targets suite)) +;; If the command line arguments are empty, re-parameterize it to +;; default to #("--help") +(define-syntax-parse-rule (parameterize-help-if-empty-ccla body ...) + (let ([ccla (current-command-line-arguments)]) + (parameterize ([current-command-line-arguments + (if (vector-empty? ccla) + #("--help") + ccla)]) + body ...))) + + (define (resyntax-analyze-parse-command-line) (define targets (box (make-vector-builder))) (define suite (box default-recommendations)) (define (add-target! target) (set-box! targets (vector-builder-add (unbox targets) target))) - (command-line - #:program "resyntax analyze" - #:multi - ("--file" filepath "A file to analyze." (add-target! (single-file-group filepath))) - ("--directory" - dirpath - "A directory to anaylze, including subdirectories." - (add-target! (directory-file-group dirpath))) - ("--package" - pkgname - "An installed package to analyze." - (add-target! (package-file-group pkgname))) - #:once-each - ("--refactoring-suite" - modpath - suite-name - "The refactoring suite to analyze code with." - (define parsed-modpath (read (open-input-string modpath))) - (define parsed-suite-name (read (open-input-string suite-name))) - (set-box! suite (dynamic-require parsed-modpath parsed-suite-name)))) + (parameterize-help-if-empty-ccla + (command-line + #:program "resyntax --analyze" + #:multi + ("--file" filepath "A file to analyze." (add-target! (single-file-group filepath))) + ("--directory" + dirpath + "A directory to anaylze, including subdirectories." + (add-target! (directory-file-group dirpath))) + ("--package" + pkgname + "An installed package to analyze." + (add-target! (package-file-group pkgname))) + #:once-each + ("--refactoring-suite" + modpath + suite-name + "The refactoring suite to analyze code with." + (define parsed-modpath (read (open-input-string modpath))) + (define parsed-suite-name (read (open-input-string suite-name))) + (set-box! suite (dynamic-require parsed-modpath parsed-suite-name))))) (resyntax-options #:targets (build-vector (unbox targets)) #:suite (unbox suite))) @@ -63,41 +77,46 @@ (define suite (box default-recommendations)) (define (add-target! target) (set-box! targets (vector-builder-add (unbox targets) target))) - (command-line - #:program "resyntax fix" - #:multi - ("--file" filepath "A file to fix." (add-target! (single-file-group filepath))) - ("--directory" - dirpath - "A directory to fix, including subdirectories." - (add-target! (directory-file-group dirpath))) - ("--package" - pkgname - "An installed package to fix." - (add-target! (package-file-group pkgname))) - #:once-each - ("--refactoring-suite" - modpath - suite-name - "The refactoring suite to analyze code with." - (define parsed-modpath (read (open-input-string modpath))) - (define parsed-suite-name (read (open-input-string suite-name))) - (set-box! suite (dynamic-require parsed-modpath parsed-suite-name)))) + (parameterize-help-if-empty-ccla + (command-line + #:program "resyntax --fix" + #:multi + ("--file" filepath "A file to fix." (add-target! (single-file-group filepath))) + ("--directory" + dirpath + "A directory to fix, including subdirectories." + (add-target! (directory-file-group dirpath))) + ("--package" + pkgname + "An installed package to fix." + (add-target! (package-file-group pkgname))) + #:once-each + ("--refactoring-suite" + modpath + suite-name + "The refactoring suite to analyze code with." + (define parsed-modpath (read (open-input-string modpath))) + (define parsed-suite-name (read (open-input-string suite-name))) + (set-box! suite (dynamic-require parsed-modpath parsed-suite-name))))) (resyntax-options #:targets (build-vector (unbox targets)) #:suite (unbox suite))) (define (resyntax-run) - (command-line - #:program "resyntax" - #:args (command . leftover-args) - (define leftover-arg-vector (vector->immutable-vector (list->vector leftover-args))) - (match command - ["analyze" - (parameterize ([current-command-line-arguments leftover-arg-vector]) - (resyntax-analyze-run))] - ["fix" - (parameterize ([current-command-line-arguments leftover-arg-vector]) - (resyntax-fix-run))]))) + (parameterize-help-if-empty-ccla + (define ccla (current-command-line-arguments)) + (command-line + #:program "resyntax" + #:once-any + ["--analyze" => (λ args (void)) ; gobble all remaining arguments + '("Analyze source code without applying changes")] + ["--fix" => (λ args (void)) ; gobble all remaining arguments + '("Analyze source code and apply changes")]) + (define command (vector-ref ccla 0)) + (define leftover-arg-vector (vector-copy ccla 1)) + (parameterize ([current-command-line-arguments leftover-arg-vector]) + (case command + [("--analyze") (resyntax-analyze-run)] + [("--fix") (resyntax-fix-run)])))) (define (resyntax-analyze-run) diff --git a/main.rkt b/main.rkt index f1aea7af..bc9c80b1 100644 --- a/main.rkt +++ b/main.rkt @@ -98,3 +98,6 @@ #:into into-hash)) (for ([(path replacement) (in-hash results-by-path)]) (file-apply-string-replacement! path replacement))) + +(module+ main + (displayln "Try `racket -l- resyntax/cli --help` instead.")) diff --git a/main.scrbl b/main.scrbl index b59bf56e..5fc69012 100644 --- a/main.scrbl +++ b/main.scrbl @@ -27,8 +27,8 @@ consider the following program: This program uses @racket[let] unnecessarily. The @racket[let] expression can be replaced with a @racket[define] form, reducing the indentation of the code. Resyntax is capable of detecting and -automatically fixing this issue. Running @exec{resyntax fix --file my-program.rkt} rewrites the above -to the following: +automatically fixing this issue. Running @exec{resyntax --fix --file my-program.rkt} rewrites the +above to the following: @(racketmod #:file "my-program.rkt" @@ -39,8 +39,8 @@ to the following: (set-box! x (unbox y)) (set-box! y t))) -To see a list of suggestions that Resyntax would apply, use @exec{resyntax analyze} instead of -@exec{resyntax fix}. Each suggestion includes an explanation of why the change is being recommended. +To see a list of suggestions that Resyntax would apply, use @exec{resyntax --analyze} instead of +@exec{resyntax --fix}. Each suggestion includes an explanation of why the change is being recommended. @bold{This tool is extremely experimental.} Do not attempt to incorporate it into your projects yet. For now, the refactoring suggestions produced by @racketmodname[resyntax] are best viewed as glimpses @@ -58,17 +58,17 @@ greatly appreciated and are best directed at the @hyperlink[github-repository-ur Resyntax provides a command-line @exec{resyntax} tool for analyzing and refactoring code. The tool has -two commands: @exec{resyntax analyze} for analyzing code without changing it, and @exec{resyntax fix} -for fixing code by applying Resyntax's suggestions. +two commands: @exec{resyntax analyze} for analyzing code without changing it, and +@exec{resyntax --fix} for fixing code by applying Resyntax's suggestions. Note that at present, Resyntax is limited in what files it can fix. Resyntax only analyzes files with the @exec{.rkt} extension where @tt{#lang racket/base} is the first line in file. -@subsection{Running @exec{resyntax analyze}} +@subsection{Running @exec{resyntax --analyze}} -The @exec{resyntax analyze} command accepts flags for specifying what modules to analyze. After +The @exec{resyntax --analyze} command accepts flags for specifying what modules to analyze. After analysis, suggestions are printed in the console. Any of the following flags can be specified any number of times: @@ -83,11 +83,11 @@ number of times: @item{@exec{--package} @nonterm{package-name} --- An installed package to analyze.}] -@subsection{Running @exec{resyntax fix}} +@subsection{Running @exec{resyntax --fix}} -The @exec{resyntax fix} command accepts the same flags as @exec{resyntax analyze} for specifying what -modules to fix. After analysis, fixes are applied and a summary is printed. +The @exec{resyntax --fix} command accepts the same flags as @exec{resyntax analyze} for specifying +what modules to fix. After analysis, fixes are applied and a summary is printed. @itemlist[ From f011ac0903052cbc5e10441df70cc17ac335f124 Mon Sep 17 00:00:00 2001 From: Metaxal Date: Sat, 31 Jul 2021 16:29:01 +0100 Subject: [PATCH 2/4] update cli docs --- main.scrbl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main.scrbl b/main.scrbl index 5fc69012..ba01ea69 100644 --- a/main.scrbl +++ b/main.scrbl @@ -58,12 +58,16 @@ greatly appreciated and are best directed at the @hyperlink[github-repository-ur Resyntax provides a command-line @exec{resyntax} tool for analyzing and refactoring code. The tool has -two commands: @exec{resyntax analyze} for analyzing code without changing it, and +two commands: @exec{resyntax --analyze} for analyzing code without changing it, and @exec{resyntax --fix} for fixing code by applying Resyntax's suggestions. Note that at present, Resyntax is limited in what files it can fix. Resyntax only analyzes files with the @exec{.rkt} extension where @tt{#lang racket/base} is the first line in file. +If @exec{resyntax} is not installed as a program but only as a Racket package, it can be run from +the command line with +@exec{racket -l- resyntax/cli --help}. + @subsection{Running @exec{resyntax --analyze}} @@ -86,7 +90,7 @@ number of times: @subsection{Running @exec{resyntax --fix}} -The @exec{resyntax --fix} command accepts the same flags as @exec{resyntax analyze} for specifying +The @exec{resyntax --fix} command accepts the same flags as @exec{resyntax --analyze} for specifying what modules to fix. After analysis, fixes are applied and a summary is printed. From 05002bfd63568bd3ff697d2d3d303dc378a25d31 Mon Sep 17 00:00:00 2001 From: Metaxal Date: Sat, 31 Jul 2021 16:50:22 +0100 Subject: [PATCH 3/4] Use for simpler hierarchical parsing --- cli.rkt | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cli.rkt b/cli.rkt index 5b6081e5..57dbd533 100644 --- a/cli.rkt +++ b/cli.rkt @@ -101,22 +101,25 @@ (resyntax-options #:targets (build-vector (unbox targets)) #:suite (unbox suite))) +;; Remove the first argument of the command line arguments +(define-syntax-parse-rule (shift-command-line-arguments body ...) + (λ args + (parameterize ([current-command-line-arguments (vector-copy (current-command-line-arguments) 1)]) + body ...))) + + (define (resyntax-run) (parameterize-help-if-empty-ccla (define ccla (current-command-line-arguments)) (command-line #:program "resyntax" #:once-any - ["--analyze" => (λ args (void)) ; gobble all remaining arguments + ["--analyze" => (shift-command-line-arguments + (resyntax-analyze-run)) '("Analyze source code without applying changes")] - ["--fix" => (λ args (void)) ; gobble all remaining arguments - '("Analyze source code and apply changes")]) - (define command (vector-ref ccla 0)) - (define leftover-arg-vector (vector-copy ccla 1)) - (parameterize ([current-command-line-arguments leftover-arg-vector]) - (case command - [("--analyze") (resyntax-analyze-run)] - [("--fix") (resyntax-fix-run)])))) + ["--fix" => (shift-command-line-arguments + (resyntax-fix-run)) + '("Analyze source code and apply changes")]))) (define (resyntax-analyze-run) From 83f520c0f0af33fa40b325ff88d5c84519662c1a Mon Sep 17 00:00:00 2001 From: Metaxal Date: Sat, 31 Jul 2021 16:52:32 +0100 Subject: [PATCH 4/4] remove dead code, reorganize --- cli.rkt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/cli.rkt b/cli.rkt index 57dbd533..2c156bad 100644 --- a/cli.rkt +++ b/cli.rkt @@ -32,6 +32,13 @@ (define-record-type resyntax-options (targets suite)) +;; Remove the first argument of the command line arguments +(define-syntax-parse-rule (shift-command-line-arguments body ...) + (λ args + (parameterize ([current-command-line-arguments (vector-copy (current-command-line-arguments) 1)]) + body ...))) + + ;; If the command line arguments are empty, re-parameterize it to ;; default to #("--help") (define-syntax-parse-rule (parameterize-help-if-empty-ccla body ...) @@ -101,16 +108,8 @@ (resyntax-options #:targets (build-vector (unbox targets)) #:suite (unbox suite))) -;; Remove the first argument of the command line arguments -(define-syntax-parse-rule (shift-command-line-arguments body ...) - (λ args - (parameterize ([current-command-line-arguments (vector-copy (current-command-line-arguments) 1)]) - body ...))) - - (define (resyntax-run) (parameterize-help-if-empty-ccla - (define ccla (current-command-line-arguments)) (command-line #:program "resyntax" #:once-any