fixed mod-date keys

pull/9/head
Matthew Butterick 11 years ago
parent c92b32fdf6
commit 54067d8f1e

@ -147,6 +147,18 @@
(check-false (template-source? "foo.html"))) (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. ;; this is for regenerate module.
;; when we want to be friendly with inputs for functions that require a path. ;; when we want to be friendly with inputs for functions that require a path.

@ -18,6 +18,10 @@
;; between development sessions (prob a worthless optimization) ;; between development sessions (prob a worthless optimization)
(define mod-dates (make-hash)) (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 ;; convert a path to a modification date value
(define/contract (path->mod-date-value path) (define/contract (path->mod-date-value path)
@ -36,11 +40,16 @@
;; therefore, use function by just listing out the paths ;; therefore, use function by just listing out the paths
(define/contract (store-refresh-in-mod-dates . rest-paths) (define/contract (store-refresh-in-mod-dates . rest-paths)
(() #:rest (listof path?) . ->* . void?) (() #:rest (listof path?) . ->* . void?)
(report (current-directory)) ;; project require files are appended to the mod-date key.
;; todo next: make this work ;; Why? So a change in a require file will trigger a refresh
(let* ([project-require-files (or (get-project-require-files) empty)] ;; (which is the right thing to do, since pollen files are
[all-files-used-in-key (append rest-paths project-require-files)]) ;; dependent on those requires)
(hash-set! mod-dates (report all-files-used-in-key) (map path->mod-date-value all-files-used-in-key)))) ;; 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 (module+ test
(reset-mod-dates) (reset-mod-dates)
@ -65,8 +74,9 @@
;; use rest argument here so calling pattern matches store-refresh ;; use rest argument here so calling pattern matches store-refresh
(define/contract (mod-date-expired? . rest-paths) (define/contract (mod-date-expired? . rest-paths)
(() #:rest (listof path?) . ->* . boolean?) (() #:rest (listof path?) . ->* . boolean?)
(or (not (rest-paths . in? . mod-dates)) ; no stored mod date (define key (make-mod-dates-key rest-paths))
(not (equal? (map path->mod-date-value rest-paths) (get mod-dates rest-paths))))) ; data has changed (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 (module+ test
(reset-mod-dates) (reset-mod-dates)
@ -106,7 +116,7 @@
(regenerate-with-pmap pmap #:force force))] (regenerate-with-pmap pmap #:force force))]
[(equal? FALLBACK_TEMPLATE_NAME (->string (file-name-from-path path))) [(equal? FALLBACK_TEMPLATE_NAME (->string (file-name-from-path path)))
(message "Regenerate: using fallback template")] (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)))]))) [else (error "Regenerate couldn't find" (->string (file-name-from-path path)))])))
(for-each &regenerate xs)) (for-each &regenerate xs))
@ -159,9 +169,9 @@
;; 2) output file doesn't exist (so it definitely won't appear in mod-dates) ;; 2) output file doesn't exist (so it definitely won't appear in mod-dates)
;; also, this is convenient for development: ;; also, this is convenient for development:
;; you can trigger a refresh just by deleting the file ;; 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) ;; 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 ;; use single quotes to escape spaces in pathnames
(let ([command (format "~a '~a' > '~a'" RACKET_PATH source-path output-path)]) (let ([command (format "~a '~a' > '~a'" RACKET_PATH source-path output-path)])
(regenerating-message (format "~a from ~a" (regenerating-message (format "~a from ~a"

@ -14,14 +14,12 @@
;; list of all eligible requires in project require directory ;; list of all eligible requires in project require directory
;; assumes current working directory is project directory (define/contract (get-project-require-files)
;; either for real, or via parameterize (-> (or/c (listof complete-path?) boolean?))
;; todo: is it possible to check this via contract? (define extras-directory (build-path pollen-file-root EXTRAS_DIR))
;; I don't think so: not possible to know ex ante whether you're in a project folder (and (directory-exists? extras-directory)
(define (get-project-require-files) ;; #:build? option returns complete paths (instead of just file names)
(and (directory-exists? EXTRAS_DIR) (let ([files (filter project-require-file? (directory-list extras-directory #:build? #t))])
;; todo: allow more than just .rkt files?
(let ([files (filter (λ(i) (has-ext? i 'rkt)) (directory-list EXTRAS_DIR #:build? #t))])
(and (not (empty? files)) files)))) (and (not (empty? files)) files))))

Loading…
Cancel
Save