~skin/zippm

7088c39496f654726ca6017c258aab8d65e7f219 — Daniel Jay Haskin 7 months ago 49afbec
Resolve conflict
3 files changed, 150 insertions(+), 99 deletions(-)

R zippm.asd => skin.djha.zippm.asd
M src/resolve.lisp
R tests/{main.lisp => resolve.lisp}
R zippm.asd => skin.djha.zippm.asd +11 -9
@@ 1,4 1,4 @@
(defsystem "zippm"
(defsystem "skin.djha.zippm"
  :version "0.1.0"
  :author "Daniel Jay Haskin"
  :license "MIT"


@@ 9,19 9,21 @@
  :components ((:module "src"
                :components
                ((:file "main")
                 (:file "version"))))
                 (:file "resolve"))))
  :description ""
  :in-order-to ((test-op (test-op "zippm/tests"))))
  :in-order-to ((test-op (test-op "skin.djha.zippm/tests"))))

(defsystem "zippm/tests"
(defsystem "skin.djha.zippm/tests"
  :author "Daniel Jay Haskin"
  :license "MIT"
  :version "0.1.0"
  :depends-on ("zippm"
               "rove")
  :depends-on ("skin.djha.zippm"
               "parachute")
  :components ((:module "tests"
                :components
                ((:file "main")
                 (:file "version"))))
                ((:file "resolve"))))
  :description "Test system for zippm"
  :perform (test-op (op c) (symbol-call :rove :run c)))
  :perform (test-op (op c)
                    (uiop:symbol-call
                      :parachute
                      :test #:skin.djha.zippm/tests/resolve)))

M src/resolve.lisp => src/resolve.lisp +56 -56
@@ 1,7 1,7 @@
#+(or)
(progn
  (declaim (optimize (speed 0) (space 0) (debug 3)))
  (dolist (x '(:cl-semver :alexandria :esrap :uiop))
  (dolist (x '("uiop" "alexandria" "cl-semver" "esrap"))
    (ql:quickload x)))

(defpackage #:skin.djha.zippm/resolve


@@ 48,10 48,10 @@
   (version
     :type cl-semver:semantic-version
     :initarg :version :reader version))
  (:documentation "A class to represent a version predicate."))
  (:documentation "a class to represent a version predicate."))

(defmethod print-object ((obj version-predicate) strm)
  (format strm "~A"
  (format strm "~a"
          (gethash (relation obj) relation-strings))
  (cl-semver:print-version (version obj) strm)
  obj)


@@ 62,28 62,28 @@

(defclass package-info ()
  ((name :initarg :name
         :initform (error "A package name is required.")
         :initform (error "a package name is required.")
         :type string
         :reader name)
   (version :initarg :version
            :type cl-semver:semantic-version
            :initform (error "A package version is required.")
            :initform (error "a package version is required.")
            :reader version)
   (location :initarg :location
             :type string
             :initform (error "A package location is required.")
             :initform (error "a package location is required.")
             :reader location)
   (requirements :initarg :requirements
                 :initform nil
                 :type list ;; of lists of version requirements
                 :reader requirements))
  (:documentation "A class to represent package information."))
  (:documentation "a class to represent package information."))

(defmethod print-object ((obj package-info) strm)
  (format strm "~A:"
  (format strm "~a:"
          (name obj))
  (cl-semver:print-version (version obj) strm)
  (format strm "@~A(~{~{~A~^|~}~^&~})"
  (format strm "@~a(~{~{~a~^|~}~^&~})"
          (location obj)
          (requirements obj))
  obj)


@@ 93,8 93,8 @@

(defparameter *requirer* :root
  "
  The requirer that will be used as the default requirer for requirements.
  This field is mostly important when building the dependency graph, at the end.
  the requirer that will be used as the default requirer for requirements.
  this field is mostly important when building the dependency graph, at the end.
  ")

(defclass requirement ()


@@ 111,10 111,10 @@
             :type requirer
             :initform *requirer*
             :reader requirer))
  (:documentation "A package requirement."))
  (:documentation "a package requirement."))

(defmethod print-object ((obj requirement) strm)
    (format strm "~:[!~;~]~A~{~{~A~^,~}~^;~}"
    (format strm "~:[!~;~]~a~{~{~a~^,~}~^;~}"
            (eql :present (status obj))
            (name obj)
            (spec obj))


@@ 127,7 127,7 @@
    :spec (spec requirement)
    :requirer requirer))

;; TODO test
;; todo test
(defun make-package-info (name version location requirements)
  (let* ((base-instance (make-instance 'package-info
                                       :name name


@@ 275,7 275,7 @@
    (cl-semver:version= (version a) (version b))))


;; This does not test requirer equality, as that would cause an infinite loop,
;; this does not test requirer equality, as that would cause an infinite loop,
;; since it represents a cycle in the graph.
(defun requirement= (a b)
  (declare (type requirement a b))


@@ 356,44 356,44 @@
    (:less-than (cl-semver:version< ver (version pred)))
    (:pess-greater (and
                     (cl-semver:version>= ver (version pred))
                     (cl-semver:make-semantic-version
                       :major
                       (1+ (cl-semver:version-major ver))
                       :minor 0
                       :patch 0)))))

(defmethod fulfills ((requirement requirement) (package package-info))
  (and
    (eql (status requirement) :present)
    (string= (name requirement) (name package))
    (every (lambda (spec)
             (some (lambda (predicate)
                     (cl-semver:satisfies? (version package) predicate))
                   spec))
           (spec requirement))))


  (with-slots (name version requirements) package
    (if (string= (name requirement) name)
      (every (lambda (spec)
               (some (lambda (predicate)
                       (cl-semver:satisfies? version predicate))
                     spec))
             (spec requirement))
      nil)))
  (let ((name (name package))
        (version (version package))
        (requirements (requirements package)))
    (if (string= (name requirement) name)
      (every (lambda (spec)
               (some (lambda (predicate)
                       (cl-semver:satisfies? version predicate))
                     spec))
             (spec requirement))
      nil)))




(defgeneric fulfills (requirement package)
  (:documentation "A generic function to determine if a package fulfills a requirement."))
                     (cl-semver:version<
                       ver
                       (cl-semver:make-semantic-version
                         (1+ (cl-semver:version-major (version pred))) 0 0))))))

;(defun requirement-fulfills (req pkg)
;  (declare (type requirement req)
;           (type package-info pkg))
;  (and
;    (eql (status requirement) :present)
;    (string= (name requirement) (name package))
;    (every (lambda (spec)
;             (some (lambda (predicate)
;                     (cl-semver:satisfies? (version package) predicate))
;                   spec))
;           (spec requirement))))
;
;  (with-slots (name version requirements) package
;    (if (string= (name requirement) name)
;      (every (lambda (spec)
;               (some (lambda (predicate)
;                       (cl-semver:satisfies? version predicate))
;                     spec))
;             (spec requirement))
;      nil)))
;  (let ((name (name package))
;        (version (version package))
;        (requirements (requirements package)))
;    (if (string= (name requirement) name)
;      (every (lambda (spec)
;               (some (lambda (predicate)
;                       (cl-semver:satisfies? version predicate))
;                     spec))
;             (spec requirement))
;      nil)))
;
;
;
;
;(defgeneric fulfills (requirement package)
;  (:documentation "A generic function to determine if a package fulfills a requirement."))

R tests/main.lisp => tests/resolve.lisp +83 -34
@@ 1,54 1,82 @@
(defpackage #:zippm/tests/resolve

#+(or)
(progn
    (ql:quickload "parachute")
    (ql:quickload "quri")
    (ql:quickload "cl-semver")
    (ql:quickload "alexandria")
    (ql:quickload "dexador")
    (ql:quickload "trivial-package-local-nicknames")
    (asdf:load-system "skin.djha.zippm")
    (asdf:test-system "skin.djha.zippm")
  )

(defpackage #:skin.djha.zippm/tests/resolve
  (:use #:cl
        #:rove)
        #:parachute
        )
  (:import-from 
        #:skin.djha.zippm/resolve)
  (:import-from
        #:cl-semver)
  (:import-from
        #:org.shirakumo.parachute
        #:define-test
        #:true
        #:false
        #:fail
        #:is
        #:isnt
        #:is-values
        #:isnt-values
        #:of-type
        #:finish
        #:test)
  (:import-from #:esrap)
  (:local-nicknames
        (#:resolve #:skin.djha.zippm/resolve)))
   (#:parachute #:org.shirakumo.parachute)
   (#:resolve #:skin.djha.zippm/resolve))
  )

(in-package #:zippm/tests/resolve)
(in-package #:skin.djha.zippm/tests/resolve)

;; NOTE: To run this test file, execute `(asdf:test-system :zippm)' in your Lisp.
+(or)
(rove:run-test *)
(test *)

(cl-semver:enable-version-syntax)

;; TODO: Get tests in for 

(define-test basic-structures)

(deftest basic-structures
  (testing
    "Make a version predicate"
    (let ((p (make-instance 'skin.djha.zippm/resolve::version-predicate
(defparameter +over1+ (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :greater-equal
                            :version #v"1.0"))
          (q (make-instance 'skin.djha.zippm/resolve::version-predicate
(defparameter +under2+ (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :less-than
                            :version #v"2.0"))
          (s (make-instance 'skin.djha.zippm/resolve::version-predicate
(defparameter +at23+ (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :equal-to
                            :version #v"2.3")))
                            :version #v"2.3"))

(defparameter +present-r+ (make-instance 'skin.djha.zippm/resolve::requirement
                            :status :present
                            :name "foo"
                            :spec
                              `(
                                (,+over1+ ,+under2+)
                                (,+at23+))))

        (ok (string=
              (format nil "~A" p)
              ">=1.0.0"))
      (let ((present-r (make-instance 'skin.djha.zippm/resolve::requirement
                              :status :present
                              :name "foo"
                              :spec
                                `(
                                  (,p ,q)
                                  (,s)))))
        (ok (string=
              (format nil "~A" present-r)
              "foo>=1.0.0,<2.0.0;==2.3.0")
(define-test "Make a version predicate"
  :parent basic-structures
  (is string= (format nil "~A" +over1+) ">=1.0.0")
  (is string= (format nil "~A" +under2+) "<2.0.0")
  (is string= (format nil "~A" +at23+) "==2.3.0")
  (is string= (format nil "~A" +present-r+) "foo>=1.0.0,<2.0.0;==2.3.0"))

              "foo>=1.0.0,<2.0.0;==2.3.0"))))
  (testing "Make a package information object"
(define-test "Make a package information object"
  :parent basic-structures
           ;; TODO: Make tests use the parse stuff
           (let ((pio
                   (resolve:make-package-info "seven-bros" (cl-semver:read-version-from-string "1.2.3") "/tmp/foo"


@@ 123,14 151,35 @@
                                                         nil
                                                         )))))
                 (pio-string "seven-bros:1.2.3@/tmp/foo(adam>=1.2.3,<=1.9.7,!=1.5.0;><3.0.0|benjamin==89.1.0;==89.5.0;==94.1.0&!caleb|caleb>=5.0.0-alpha.3,<5.0.0&daniel)"))
             (ok (string= (format nil "~A" pio)
             (true (string= (format nil "~A" pio)
                          pio-string))
             (ok (resolve:package-info= (esrap:parse 'resolve::package-info pio-string)
             (true (resolve:package-info= (esrap:parse 'resolve::package-info pio-string)
                        pio))
             (ok (string= (format nil "~A" (esrap:parse 'resolve::package-info pio-string))
                         pio-string))

(ok (

             (true (string= (format nil "~A" (esrap:parse 'resolve::package-info pio-string))
                         pio-string))))

(define-test fulfillments)

(define-test "version passes"
  :parent fulfillments
    (let ((p (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :greater-equal
                            :version #v"2.0"))
          (q (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :less-than
                            :version #v"3.0"))
          (s (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :equal-to
                            :version #v"3.3"))
          (u (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :pess-greater
                            :version #v"2.0"))
          (w (make-instance 'skin.djha.zippm/resolve::version-predicate
                            :relation :pess-greater
                            :version #v"1.0"))
          (v #v"2.5"))
      (true (resolve::version-passes v p))
      (true (resolve::version-passes v q))
      (true (not (resolve::version-passes v s)))
      (true (resolve::version-passes v u))
      (true (not (resolve::version-passes v w)))))