From 54067d8f1eb4c478b3929e5df13ffd135e82c196 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sat, 14 Sep 2013 10:30:53 -0700 Subject: [PATCH] fixed mod-date keys --- pollen-file-tools.rkt | 12 ++++++++++++ regenerate.rkt | 30 ++++++++++++++++++++---------- tools.rkt | 14 ++++++-------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/pollen-file-tools.rkt b/pollen-file-tools.rkt index 7911c64..918e602 100644 --- a/pollen-file-tools.rkt +++ b/pollen-file-tools.rkt @@ -147,6 +147,18 @@ (check-false (template-source? "foo.html"))) +;; predicate for files that are eligible to be required +;; from the project/require directory +;; todo: extend this beyond just racket files? +(define/contract (project-require-file? x) + (any/c . -> . boolean?) + (has-ext? (->path x) 'rkt)) + +(module+ test + (check-true (project-require-file? "foo.rkt")) + (check-false (project-require-file? "foo.html"))) + + ;; this is for regenerate module. ;; when we want to be friendly with inputs for functions that require a path. diff --git a/regenerate.rkt b/regenerate.rkt index 350a5bd..4d6cb83 100644 --- a/regenerate.rkt +++ b/regenerate.rkt @@ -18,6 +18,10 @@ ;; between development sessions (prob a worthless optimization) (define mod-dates (make-hash)) +(define/contract (make-mod-dates-key paths) + ((listof path?) . -> . (listof path?)) + (define project-require-files (or (get-project-require-files) empty)) + (flatten (append paths project-require-files))) ;; convert a path to a modification date value (define/contract (path->mod-date-value path) @@ -36,11 +40,16 @@ ;; therefore, use function by just listing out the paths (define/contract (store-refresh-in-mod-dates . rest-paths) (() #:rest (listof path?) . ->* . void?) - (report (current-directory)) - ;; todo next: make this work - (let* ([project-require-files (or (get-project-require-files) empty)] - [all-files-used-in-key (append rest-paths project-require-files)]) - (hash-set! mod-dates (report all-files-used-in-key) (map path->mod-date-value all-files-used-in-key)))) + ;; project require files are appended to the mod-date key. + ;; Why? So a change in a require file will trigger a refresh + ;; (which is the right thing to do, since pollen files are + ;; dependent on those requires) + ;; It's convenient for development, because otherwise + ;; you'd need to restart the server when you change a require + ;; or explicitly use the force parameter. + ;; This way, require files and pollen files have the same behavior. + (define key (make-mod-dates-key rest-paths)) + (hash-set! mod-dates key (map path->mod-date-value key))) (module+ test (reset-mod-dates) @@ -65,8 +74,9 @@ ;; use rest argument here so calling pattern matches store-refresh (define/contract (mod-date-expired? . rest-paths) (() #:rest (listof path?) . ->* . boolean?) - (or (not (rest-paths . in? . mod-dates)) ; no stored mod date - (not (equal? (map path->mod-date-value rest-paths) (get mod-dates rest-paths))))) ; data has changed + (define key (make-mod-dates-key rest-paths)) + (or (not (key . in? . mod-dates)) ; no stored mod date + (not (equal? (map path->mod-date-value key) (get mod-dates key))))) ; data has changed (module+ test (reset-mod-dates) @@ -106,7 +116,7 @@ (regenerate-with-pmap pmap #:force force))] [(equal? FALLBACK_TEMPLATE_NAME (->string (file-name-from-path path))) (message "Regenerate: using fallback template")] - [(file-exists? path) (message "Regenerate: nothing to be done with" (->string (file-name-from-path path)))] + [(file-exists? path) 'pass-through] [else (error "Regenerate couldn't find" (->string (file-name-from-path path)))]))) (for-each ®enerate xs)) @@ -159,9 +169,9 @@ ;; 2) output file doesn't exist (so it definitely won't appear in mod-dates) ;; also, this is convenient for development: ;; you can trigger a refresh just by deleting the file - (not (file-exists? output-path)) + (not (file-exists? output-path)) ;; 3) file otherwise needs refresh (e.g., it changed) - (mod-date-expired? source-path)) + (mod-date-expired? source-path)) ;; use single quotes to escape spaces in pathnames (let ([command (format "~a '~a' > '~a'" RACKET_PATH source-path output-path)]) (regenerating-message (format "~a from ~a" diff --git a/tools.rkt b/tools.rkt index ccaf20e..48c9cad 100644 --- a/tools.rkt +++ b/tools.rkt @@ -14,14 +14,12 @@ ;; list of all eligible requires in project require directory -;; assumes current working directory is project directory -;; either for real, or via parameterize -;; todo: is it possible to check this via contract? -;; I don't think so: not possible to know ex ante whether you're in a project folder -(define (get-project-require-files) - (and (directory-exists? EXTRAS_DIR) - ;; todo: allow more than just .rkt files? - (let ([files (filter (λ(i) (has-ext? i 'rkt)) (directory-list EXTRAS_DIR #:build? #t))]) +(define/contract (get-project-require-files) + (-> (or/c (listof complete-path?) boolean?)) + (define extras-directory (build-path pollen-file-root EXTRAS_DIR)) + (and (directory-exists? extras-directory) + ;; #:build? option returns complete paths (instead of just file names) + (let ([files (filter project-require-file? (directory-list extras-directory #:build? #t))]) (and (not (empty? files)) files))))