]> asedeno.scripts.mit.edu Git - cl-protobufs.git/commitdiff
process new .proto-imports file when compiling and loading components
authorAlejandro R Sedeño <asedeno@google.com>
Wed, 5 Dec 2012 01:33:31 +0000 (20:33 -0500)
committerAlejandro R Sedeño <asedeno@google.com>
Wed, 5 Dec 2012 21:14:39 +0000 (16:14 -0500)
asdf-support.lisp
pkgdcl.lisp

index ae716d78ab32623cdfe2a3f30ad366d2c5f041ac..cee05d9247093349a697a503bdb8b7a242de6183 100644 (file)
   (format nil (compatfmt "~@<proto-compiling ~3i~_~A~@:>")
           (first (input-files op component))))
 
+(defmethod input-files ((op load-op) (component protobuf-file))
+  "The input files are the .fasl and .proto-imports files."
+  (declare (ignorable op))
+  (append (output-files (make-instance 'compile-op) component) ; fasl
+          (cdr (output-files (make-instance 'proto-to-lisp) component)))) ; proto-imports
+
 (defmethod perform ((op compile-op) (component protobuf-file))
   (let* ((input  (protobuf-input-file component))
          (output (output-file op component))
          (proto-impl:*protobuf-output-path* output)
          (*compile-file-warnings-behaviour* (operation-on-warnings op))
          (*compile-file-failure-behaviour* (operation-on-failure op)))
+    (proto-impl:process-imports-from-file
+     (make-pathname :type "proto-imports"
+                    :defaults output))
     (multiple-value-bind (output warnings-p failure-p)
         (apply #'compile-file* lisp
                :output-file fasl
         (error 'compile-error
                :component component :operation op)))))
 
+(defmethod perform ((op load-op) (component protobuf-file))
+  (let* ((input  (protobuf-input-file component))
+         (paths  (cons (directory-namestring input) (resolve-search-path component)))
+         (proto-impl:*protobuf-search-path* paths)
+         (proto-impl:*protobuf-output-path* (first (input-files op component))))
+    (proto-impl:process-imports-from-file
+     (make-pathname :type "proto-imports"
+                    :defaults (first (input-files op component)))))
+  (call-next-method))
+
 (defmethod operation-description ((op compile-op) (component protobuf-file))
   (format nil (compatfmt "~@<compiling ~3i~_~A~@:>")
           (first (input-files op component))))
   lisp-file)
 
 ;; Process 'import' lines
-(defun process-imports (schema imports
-                        &key (search-path *protobuf-search-path*)
-                             (output-path *protobuf-output-path*))
+(defun process-imports (schema imports)
   "Imports all of the files given by 'imports'.
    If the file is a .proto file, it first parses it and writes a .lisp file.
    The .lisp file is the compiled and loaded."
           (setf (proto-imported-schemas schema)
                 (nconc (proto-imported-schemas schema) (list imported)))
           (return-from import-one))
-        (dolist (path search-path (error "Could not import ~S" import))
-          (let* ((base-path  (asdf::merge-pathnames* import path))
-                 (proto-file (make-pathname :name import-name :type "proto"
-                                            :defaults base-path))
-                 (lisp-file  (asdf::lispize-pathname
-                              (if output-path
-                                (make-pathname :name import-name
-                                               :directory (pathname-directory output-path))
-                                base-path)))
-                 (imports-file (make-pathname :type "proto-imports"
-                                              :defaults lisp-file))
-                 (fasl-file  (compile-file-pathname lisp-file))
-                 (asdf:*asdf-verbose* nil)      ;for safe-file-write-date
-                 (proto-date (asdf::safe-file-write-date proto-file))
-                 (lisp-date  (asdf::safe-file-write-date lisp-file))
-                 (fasl-date  (asdf::safe-file-write-date fasl-file)))
-            (when (probe-file proto-file)
-              (let ((*protobuf-pathname* proto-file))
-                (when (string= (pathname-type base-path) "proto")
-                  ;; The user asked to import a .proto file
-                  ;; If there's no .lisp file or an older .lisp file, parse the .proto file now
-                  (cond ((not proto-date)
-                         (warn "Could not find the .proto file to be imported: ~A" proto-file))
-                        ((or (not lisp-date)
-                            (< lisp-date proto-date))
-                         (parse-protobuf-file proto-file lisp-file imports-file)
-                         (setq lisp-date (file-write-date lisp-file)))))
-                ;; Compile the .lisp file, if necessary
-                (cond ((not lisp-date)
-                       (unless (string= (pathname-type base-path) "proto")
-                         (warn "Could not find the .lisp file to be compiled: ~A" lisp-file)))
-                      (t
-                       (when (or (not fasl-date)
-                                 (< fasl-date lisp-date))
-                         (let ((*compile-file-pathname* lisp-file)
-                               (*load-pathname* nil))
-                           (setq fasl-file (compile-file lisp-file)))
-                         (setq fasl-date (file-write-date fasl-file)))
-                       ;; Now we can load the .fasl file
-                       (let ((*compile-file-pathname* nil)
-                             (*load-pathname* fasl-file))
-                         (load fasl-file)))))
-              (let* ((imported (find-schema (class-name->proto import-name))))
-                (when imported
-                  (setf (proto-imported-schemas schema)
-                        (nconc (proto-imported-schemas schema) (list imported))))
-                (return-from import-one)))))))))
+        (%process-import import import-name)
+        (let* ((imported (find-schema (class-name->proto import-name))))
+          (when imported
+            (setf (proto-imported-schemas schema)
+                  (nconc (proto-imported-schemas schema) (list imported))))
+          (return-from import-one))))))
+
+(defun process-imports-from-file (imports-file)
+  (when (probe-file imports-file)
+    (let ((imports (with-open-file (stream imports-file
+                                    :direction :input
+                                    :external-format :utf-8
+                                    :element-type 'character)
+                     (with-standard-io-syntax (read stream)))))
+      (dolist (import imports)
+        (let* ((import      (pathname import))
+               (import-name (pathname-name import)))
+          ;; If this schema has already been loaded, we're done.
+          (unless (find-schema (class-name->proto import-name))
+            (%process-import import import-name)))))))
+
+(defun %process-import (import import-name
+                        &key (search-path *protobuf-search-path*)
+                             (output-path *protobuf-output-path*))
+  (dolist (path search-path (error "Could not import ~S" import))
+    (let* ((base-path  (asdf::merge-pathnames* import path))
+           (proto-file (make-pathname :name import-name :type "proto"
+                                      :defaults base-path))
+           (lisp-file  (asdf::lispize-pathname
+                        (if output-path
+                            (make-pathname :name import-name
+                                           :directory (pathname-directory output-path))
+                            base-path)))
+           (imports-file (make-pathname :type "proto-imports"
+                                        :defaults lisp-file))
+           (fasl-file  (compile-file-pathname lisp-file))
+           (asdf:*asdf-verbose* nil)    ;for safe-file-write-date
+           (proto-date (asdf::safe-file-write-date proto-file))
+           (lisp-date  (asdf::safe-file-write-date lisp-file))
+           (fasl-date  (asdf::safe-file-write-date fasl-file))
+           (imports-date  (asdf::safe-file-write-date imports-file)))
+      (when (probe-file proto-file)
+        (let ((*protobuf-pathname* proto-file))
+          (when (string= (pathname-type base-path) "proto")
+            ;; The user asked to import a .proto file
+            ;; If there's no .lisp file or an older .lisp file, or no
+            ;; .proto-imports file or an older .proto-imports file parse
+            ;; the .proto file now
+            ;; If we did not parse the .proto file, process the generated
+            ;; .proto-imports file now.
+            (cond ((not proto-date)
+                   (warn "Could not find the .proto file to be imported: ~A" proto-file))
+                  ((or (not (and lisp-date imports-date))
+                       (< lisp-date proto-date)
+                       (< imports-date proto-date))
+                   (parse-protobuf-file proto-file lisp-file imports-file)
+                   (setq lisp-date (file-write-date lisp-file))
+                   (setq imports-date (file-write-date imports-file)))
+                  (t
+                   (process-imports-from-file imports-file))))
+          ;; Compile the .lisp file, if necessary
+          (cond ((not lisp-date)
+                 (unless (string= (pathname-type base-path) "proto")
+                   (warn "Could not find the .lisp file to be compiled: ~A" lisp-file)))
+                (t
+                 (when (or (not fasl-date)
+                           (< fasl-date lisp-date))
+                   (let ((*compile-file-pathname* lisp-file)
+                         (*load-pathname* nil))
+                     (setq fasl-file (compile-file lisp-file)))
+                   (setq fasl-date (file-write-date fasl-file)))))
+          ;; Load the .fasl file
+          (cond ((not fasl-date)
+                 (unless (string= (pathname-type base-path) "proto")
+                   (warn "Could not find the .fasl file to be loaded: ~A" fasl-file)))
+                (t
+                 (let ((*compile-file-pathname* nil)
+                       (*load-pathname* fasl-file))
+                   (load fasl-file)))))
+        (return (values))))))
index da803817ad5c90749d03df32c9cab51a14fa5fa1..7841c56bbefd70f52c458c441e9ff082f23b6be8 100644 (file)
    ;; Stuff for ASDF
    "PARSE-PROTOBUF-FILE"
    "PROCESS-IMPORTS"
+   "PROCESS-IMPORTS-FROM-FILE"
 
    ;; Stuff for RPC stubs
    "*RPC-PACKAGE*"