From 1f1bee90fd5347f0481e8690c8e142a0ed3944cf Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Wed, 21 Oct 2020 13:37:23 -0700 Subject: [PATCH] correct pagetree rendering (fixes #237) --- pollen/private/ts.rktd | 2 +- pollen/render.rkt | 38 ++++++++++++-------- pollen/test/data/pagetree-output/bar.txt.pp | 3 ++ pollen/test/data/pagetree-output/foo.txt.pp | 3 ++ pollen/test/data/pagetree-output/index.ptree | 4 +++ pollen/test/test-pagetree-output.rkt | 27 ++++++++++++++ pollen/test/test-poly-output-path.rkt | 2 +- 7 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 pollen/test/data/pagetree-output/bar.txt.pp create mode 100644 pollen/test/data/pagetree-output/foo.txt.pp create mode 100644 pollen/test/data/pagetree-output/index.ptree create mode 100644 pollen/test/test-pagetree-output.rkt diff --git a/pollen/private/ts.rktd b/pollen/private/ts.rktd index 39a6ffa..2da2df3 100644 --- a/pollen/private/ts.rktd +++ b/pollen/private/ts.rktd @@ -1 +1 @@ -1603077405 +1603312643 diff --git a/pollen/render.rkt b/pollen/render.rkt index 7e81daf..37668ce 100644 --- a/pollen/render.rkt +++ b/pollen/render.rkt @@ -127,10 +127,10 @@ ;; if it was a legit error, the render will stop and print a trace. ;; crashed jobs are completed jobs that weren't finished (define failed-source-paths (for/list ([(path finished?) (in-dict completed-jobs)] - #:unless finished?) - path)) + #:unless finished?) + path)) (define failed-output-paths (for/list ([source-path (in-list failed-source-paths)]) - (dict-ref source-to-output-path-table source-path))) + (dict-ref source-to-output-path-table source-path))) (list failed-source-paths failed-output-paths)] [else (match (apply sync worker-evts) @@ -178,23 +178,31 @@ ;; meaning, if source is "test.poly.pm" and we get `raco pollen render test.txt`, ;; then the output path argument should force .txt rendering, regardless of `current-poly-target` setting ;; so the output path may contain information we need that we can't necessarily derive from the source path. - (define expanded-source-paths - (let loop ([paths paths-in] [acc null]) + + (define-values (expanded-source-paths expanded-output-paths) + ;; we generate the output paths in parallel with the source paths + ;; rather than afterward, because + ;; for poly files we want to be able to look at + ;; the original path provided as an argument + ;; but the path arguments might also include pagetrees, + ;; which expand to multiple files. + ;; so this keeps everything correlated correctly. + (let loop ([paths paths-in] [sps null] [ops null]) (match paths - [(? null?) (sort (remove-duplicates acc) stringstring)] + [(? null?) + (define (cleanup paths) + (sort (remove-duplicates paths) stringstring)) + (apply values (map cleanup (list sps ops)))] [(cons path rest) (match (->complete-path path) [(? pagetree-source? pt) - (loop (append (pagetree->paths pt) rest) acc)] + (loop (append (pagetree->paths pt) rest) sps ops)] [(app ->source-path (and (not #false) (? file-exists?) sp)) - (loop rest (cons sp acc))] - [_ (loop rest acc)])]))) - (define expanded-output-paths - (for/list ([path (in-list paths-in)] - [sp (in-list expanded-source-paths)]) - (if (equal? (->output-path path) path) - path - (->output-path sp)))) + (define op (match path + [(== (->output-path path)) path] + [_ (->output-path sp)])) + (loop rest (cons sp sps) (cons op ops))] + [_ (loop rest sps ops)])]))) (cond [(null? expanded-source-paths) (message "[no paths to render]")] [(eq? special-output 'dry-run) (for-each message expanded-source-paths)] diff --git a/pollen/test/data/pagetree-output/bar.txt.pp b/pollen/test/data/pagetree-output/bar.txt.pp new file mode 100644 index 0000000..95b102a --- /dev/null +++ b/pollen/test/data/pagetree-output/bar.txt.pp @@ -0,0 +1,3 @@ +#lang pollen + +this is bar \ No newline at end of file diff --git a/pollen/test/data/pagetree-output/foo.txt.pp b/pollen/test/data/pagetree-output/foo.txt.pp new file mode 100644 index 0000000..94b78fa --- /dev/null +++ b/pollen/test/data/pagetree-output/foo.txt.pp @@ -0,0 +1,3 @@ +#lang pollen + +this is foo \ No newline at end of file diff --git a/pollen/test/data/pagetree-output/index.ptree b/pollen/test/data/pagetree-output/index.ptree new file mode 100644 index 0000000..f5b1381 --- /dev/null +++ b/pollen/test/data/pagetree-output/index.ptree @@ -0,0 +1,4 @@ +#lang pollen/ptree + +foo.txt +bar.txt \ No newline at end of file diff --git a/pollen/test/test-pagetree-output.rkt b/pollen/test/test-pagetree-output.rkt new file mode 100644 index 0000000..e8eecb8 --- /dev/null +++ b/pollen/test/test-pagetree-output.rkt @@ -0,0 +1,27 @@ +#lang at-exp racket/base +(require rackunit racket/runtime-path pollen/render racket/file pollen/setup) + +;; define-runtime-path only allowed at top level +(define-runtime-path dir "data/pagetree-output") +(define-runtime-path index.ptree "data/pagetree-output/index.ptree") +(define-runtime-path foo.txt.pp "data/pagetree-output/foo.txt.pp") +(define-runtime-path foo.txt "data/pagetree-output/foo.txt") +(define-runtime-path bar.txt.pp "data/pagetree-output/bar.txt.pp") +(define-runtime-path bar.txt "data/pagetree-output/bar.txt") +(define-runtime-path pollen-cache "data/pagetree-output/compiled") + +(parameterize ([current-output-port (open-output-string)] + [current-directory dir] + [current-project-root dir]) + + ;; passing "index.ptree" as argument should work + (for ([parallel? (list #true #false)]) + (render-batch #:parallel parallel? index.ptree) + (check-true (file-exists? foo.txt)) + (check-equal? (file->string foo.txt) "this is foo") + (delete-file foo.txt) + (check-true (file-exists? bar.txt)) + (check-equal? (file->string bar.txt) "this is bar") + (delete-file bar.txt))) + +(delete-directory/files pollen-cache) \ No newline at end of file diff --git a/pollen/test/test-poly-output-path.rkt b/pollen/test/test-poly-output-path.rkt index 4be1c82..cdeab5c 100644 --- a/pollen/test/test-poly-output-path.rkt +++ b/pollen/test/test-poly-output-path.rkt @@ -1,5 +1,5 @@ #lang at-exp racket/base -(require rackunit racket/runtime-path pollen/render racket/file racket/system pollen/setup txexpr xml) +(require rackunit racket/runtime-path pollen/render racket/file pollen/setup txexpr xml) ;; define-runtime-path only allowed at top level (define-runtime-path poly-output-path-dir "data/poly-output-path")