-(defun operate (operation-class system &rest args)
- (let* ((op (apply #'make-instance operation-class
- :original-initargs args args))
- (system (if (typep system 'component) system (find-system system)))
- (steps (traverse op system)))
- (with-compilation-unit ()
- (loop for (op . component) in steps do
- (loop
- (restart-case
- (progn (perform op component)
- (return))
- (retry-component ())
- (skip-component () (return))))))))
-
-(defun oos (&rest args)
- "Alias of OPERATE function"
- (apply #'operate args))
+(defun operate (operation-class system &rest args &key (verbose t) version force
+ &allow-other-keys)
+ (declare (ignore force))
+ (let* ((*package* *package*)
+ (*readtable* *readtable*)
+ (op (apply #'make-instance operation-class
+ :original-initargs args
+ args))
+ (*verbose-out* (if verbose *standard-output* (make-broadcast-stream)))
+ (system (if (typep system 'component) system (find-system system))))
+ (unless (version-satisfies system version)
+ (error 'missing-component-of-version :requires system :version version))
+ (let ((steps (traverse op system)))
+ (with-compilation-unit ()
+ (loop for (op . component) in steps do
+ (loop
+ (restart-case
+ (progn (perform op component)
+ (return))
+ (retry ()
+ :report
+ (lambda (s)
+ (format s "~@<Retry performing ~S on ~S.~@:>"
+ op component)))
+ (accept ()
+ :report
+ (lambda (s)
+ (format s "~@<Continue, treating ~S on ~S as ~
+ having been successful.~@:>"
+ op component))
+ (setf (gethash (type-of op)
+ (component-operation-times component))
+ (get-universal-time))
+ (return)))))))))
+
+(defun oos (operation-class system &rest args &key force (verbose t) version
+ &allow-other-keys)
+ (declare (ignore force verbose version))
+ (apply #'operate operation-class system args))
+
+(let ((operate-docstring
+ "Operate does three things:
+
+1. It creates an instance of `operation-class` using any keyword parameters
+as initargs.
+2. It finds the asdf-system specified by `system` (possibly loading
+it from disk).
+3. It then calls `traverse` with the operation and system as arguments
+
+The traverse operation is wrapped in `with-compilation-unit` and error
+handling code. If a `version` argument is supplied, then operate also
+ensures that the system found satisfies it using the `version-satisfies`
+method."))
+ (setf (documentation 'oos 'function)
+ (format nil
+ "Short for _operate on system_ and an alias for the [operate][] function. ~&~&~a"
+ operate-docstring))
+ (setf (documentation 'operate 'function)
+ operate-docstring))
+
+(defun load-system (system &rest args &key force (verbose t) version)
+ "Shorthand for `(operate 'asdf:load-op system)`. See [operate][] for details."
+ (declare (ignore force verbose version))
+ (apply #'operate 'load-op system args))
+
+(defun compile-system (system &rest args &key force (verbose t) version)
+ "Shorthand for `(operate 'asdf:compile-op system)`. See [operate][] for details."
+ (declare (ignore force verbose version))
+ (apply #'operate 'compile-op system args))
+
+(defun test-system (system &rest args &key force (verbose t) version)
+ "Shorthand for `(operate 'asdf:test-op system)`. See [operate][] for details."
+ (declare (ignore force verbose version))
+ (apply #'operate 'test-op system args))