Skip to content
67 changes: 67 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: CI

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
test:
# The type of runner that the job will run on
runs-on: ${{matrix.os}}

strategy:
matrix:
os: [ubuntu-latest]
lisp:
- ccl
- sbcl
- allegro
# - clasp
# - clisp
- ecl
# - lispworks Lispworks Roswell install is broken
- mkcl

steps:
- uses: actions/checkout@v3

# Lisp setup copied from here: https://github.com/3b/ci-example/blob/master/.github/workflows/CI.yml
- name: cache .roswell
id: cache-dot-roswell
uses: actions/cache@v1
with:
path: ~/.roswell
key: ${{ runner.os }}-dot-roswell-${{ matrix.lisp }}-${{ hashFiles('**/*.asd') }}
restore-keys: |
${{ runner.os }}-dot-roswell-${{ matrix.lisp }}-
${{ runner.os }}-dot-roswell-

- name: install roswell
shell: bash
# always run install, since it does some global installs and setup that isn't cached
env:
LISP: ${{ matrix.lisp }}
# Use a previous release of Roswell to avoid error encountered
# due to libcurl3 not being available.
# Source of fix: https://github.com/avodonosov/drakma/commit/fbba29181ba2962f5031da581bd2de4dac98733d
run: |
sudo apt-get install -y libcurl4
curl -L https://raw.githubusercontent.com/roswell/roswell/release/scripts/install-for-ci.sh | sh

# Compile first in a separate step to make the test output more readable
- name: compile cl-json library
shell: bash
run: |
ros -l $PWD/compile-cl-json.lisp
- name: tests
shell: bash
run: |
ros -l $PWD/test-cl-json.lisp
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ testcases includes the JSON_checker tests.
* 2009 New alternative encoder, the explicit sexp-encoder.
* 2011 Json-rpc version 2 format by Robert Goldman.
* 2012 Move from darcs to git.
* 2020 Forking to sharplispers to take project into community maintenance.

## Licence

Expand Down
13 changes: 6 additions & 7 deletions cl-json.asd
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
:name "cl-json"
:description "JSON in Lisp. JSON (JavaScript Object Notation) is a lightweight data-interchange format."
:version "0.5.0"
:maintainer "Henrik Hjelte <henrik@henrikhjelte.com>"
:author "Henrik Hjelte <henrik@henrikhjelte.com>"
:maintainer "Robert P. Goldman <rpgoldman@sift.net>"
:licence "MIT"
:in-order-to ((test-op (test-op "cl-json.test")))
:in-order-to ((test-op (test-op "cl-json/test")))
:components ((:static-file "cl-json.asd")
(:module :src
:components ((:file "package")
Expand All @@ -37,20 +38,18 @@
(:file "utils" :depends-on ("decoder" "encoder"))
(:file "json-rpc" :depends-on ("package" "common" "utils" "encoder" "decoder"))))))

(defsystem :cl-json.test
(defsystem :cl-json/test
:depends-on (:cl-json :fiveam )
;; newer ASDF versions have this implicitly, but I know of no good way to detect this. [2010/01/02:rpg]
:in-order-to ((test-op (load-op "cl-json.test")))
:components ((:module :t
:components ((:file "package")
(:file "testmisc" :depends-on ("package" "testdecoder" "testencoder"))
(:file "testdecoder" :depends-on ("package"))
(:file "testencoder" :depends-on ("package"))))))

(defmethod perform ((op test-op) (c (eql (find-system :cl-json.test))))
(defmethod perform ((op test-op) (c (eql (find-system :cl-json/test))))
(funcall (intern (symbol-name '#:run!) :it.bese.FiveAM)
(intern (symbol-name '#:json) :json-test)))

(defparameter *cl-json-directory*
(make-pathname :directory (pathname-directory *load-truename*)))
(system-relative-pathname "cl-json" ""))

53 changes: 53 additions & 0 deletions compile-cl-json.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
(defpackage compile-cl-json
(:use :common-lisp))

(in-package :compile-cl-json)

(require :asdf)

(asdf:initialize-source-registry '(:source-registry (:directory :here)
:inherit-configuration))

(declaim (optimize (speed 3) (space 3)))

(defun leave-lisp (message return)
(fresh-line *error-output*)
(when message
(format *error-output* message)
(terpri *error-output*))
(finish-output *error-output*)
(finish-output *standard-output*)
(uiop:quit return))

(defmacro quit-on-error (&body body)
`(call-quitting-on-error (lambda () ,@body)))

(defun call-quitting-on-error (thunk)
"Unless the environment variable DEBUG_CL_JSON_TEST
is bound, write a message and exit on an error. If
*asdf-test-debug* is true, enter the debugger."
(handler-bind
((error (lambda (c)
(format *error-output* "~&~a~&" c)
(cond
((ignore-errors (funcall (find-symbol "GETENV" :asdf) "DEBUG_CL_JSON_TEST"))
(break))
(t
(finish-output *standard-output*)
(finish-output *trace-output*)
(format *error-output* "~&ABORTING:~% ~S~%" c)
#+sbcl (sb-debug:backtrace 69)
#+clozure (ccl:print-call-history :count 69 :start-frame-number 1)
#+clisp (system::print-backtrace)
(format *error-output* "~&ABORTING:~% ~S~%" c)
(finish-output *error-output*)
(leave-lisp "~&Script failed~%" 1))))))
(funcall thunk)
(leave-lisp "~&Script succeeded~%" 0)))


(quit-on-error
(ql:quickload "fiveam")
(asdf:compile-system "cl-json"))


2 changes: 1 addition & 1 deletion t/testdecoder.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ safe-symbols-parsing function here for a cure."


(defparameter *json-test-files-path*
(asdf:system-relative-pathname "cl-json.test" "t/"))
(asdf:system-relative-pathname "cl-json/test" "t/"))

(defun test-file (name)
(make-pathname :name name :type "json" :defaults *json-test-files-path*))
Expand Down
57 changes: 57 additions & 0 deletions test-cl-json.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
(defpackage testing-cl-json
(:use common-lisp))

(in-package :testing-cl-json)

(require :asdf)

(asdf:initialize-source-registry '(:source-registry (:directory :here)
:inherit-configuration))

(defun leave-lisp (message return)
(fresh-line *error-output*)
(when message
(format *error-output* message)
(terpri *error-output*))
(finish-output *error-output*)
(finish-output *standard-output*)
(uiop:quit return))

(defmacro quit-on-error (&body body)
`(call-quitting-on-error (lambda () ,@body)))

(defun call-quitting-on-error (thunk)
"Unless the environment variable DEBUG_CL_JSON_TEST
is bound, write a message and exit on an error. If
*asdf-test-debug* is true, enter the debugger."
(flet ((quit (c desc)
(format *error-output* "~&Encountered ~a during test.~%~a~%" desc c)
(cond
;; decline to handle the error.
((ignore-errors (funcall (find-symbol "GETENV" :asdf) "DEBUG_CL_JSON_TEST"))
(format t "~&Interactive mode (DEBUG_CL_JSON_TEST) -- Invoke debugger.~%")
(invoke-debugger c))
(t
(finish-output *standard-output*)
(finish-output *trace-output*)
(format *error-output* "~&ABORTING:~% ~S~%" c)
(uiop:print-condition-backtrace c)
(format *error-output* "~&ABORTING:~% ~S~%" c)
(finish-output *error-output*)
(leave-lisp "~&Script failed~%" 1)))))
(handler-bind
((error (lambda (c)
(quit c "ERROR")))
(storage-condition
(lambda (c) (quit c "STORAGE-CONDITION")))
(serious-condition (lambda (c)
(quit c "Other SERIOUS-CONDIITON"))))
(funcall thunk)
(format t "~&Script succeeded~%")
t)))

(quit-on-error
(format t "~&;;; Testing CL-JSON on ~a.~%" (lisp-implementation-type))
(asdf:test-system "cl-json"))

(uiop:quit 0)