-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
642 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
on: [push] | ||
jobs: | ||
tests: | ||
strategy: | ||
matrix: | ||
os: | ||
- ubuntu-latest | ||
- macos-latest | ||
# I cannot get windows working for any implementations | ||
# - windows-latest | ||
lisp: | ||
- sbcl-bin | ||
# The following doesn't work | ||
# - ecl | ||
# - ccl-bin | ||
# - abcl-bin | ||
# - clasp-bin | ||
# - cmu-bin | ||
# - clisp-head | ||
runs-on: ${{ matrix.os }} | ||
env: | ||
LISP: ${{ matrix.lisp }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: 40ants/setup-lisp@v4 | ||
with: | ||
asdf-system: sijo-version/tests | ||
qlfile-template: | | ||
dist ultralisp http://dist.ultralisp.org | ||
- uses: 40ants/run-tests@v2 | ||
with: | ||
asdf-system: sijo-version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
*.FASL | ||
*.fasl | ||
*.lisp-temp | ||
*.dfsl | ||
*.pfsl | ||
*.d64fsl | ||
*.p64fsl | ||
*.lx64fsl | ||
*.lx32fsl | ||
*.dx64fsl | ||
*.dx32fsl | ||
*.fx64fsl | ||
*.fx32fsl | ||
*.sx64fsl | ||
*.sx32fsl | ||
*.wx64fsl | ||
*.wx32fsl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
Semantic version for your systems. Opinionated defaults, but flexible. | ||
|
||
* Installation | ||
Clone repository | ||
#+begin_src bash :eval never | ||
git clone [email protected]:simendsjo/sijo-version.git ~/quicklisp/local-projects/sijo-version | ||
#+end_src | ||
|
||
* Use | ||
Load library | ||
#+begin_src lisp :exports code | ||
(ql:quickload :sijo-version) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
| :SIJO-VERSION | | ||
|
||
Call ~version~ to get a calculated semver version. | ||
|
||
#+begin_src lisp :exports both :eval never | ||
(sijo-version:version) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: 0.1.0-0.dev.27+prototype.7aeedb4d32927e19a5e9ed406ac5735db0fd20dd.20240301145715Z | ||
|
||
When supplying the values manually, those will be used instead | ||
|
||
#+begin_src lisp :exports both | ||
(sijo-version:version :version "1.2.3" :pre-release nil :build-metadata nil) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: 1.2.3 | ||
|
||
#+begin_src lisp :exports both | ||
(sijo-version:version :version "1.2.3" :pre-release "some-prerelease" :build-metadata nil) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: 1.2.3-some-prerelease | ||
|
||
#+begin_src lisp :exports both | ||
(sijo-version:version :version "1.2.3" :pre-release "some-prerelease" :build-metadata "some-build-info") | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: 1.2.3-some-prerelease+some-build-info | ||
|
||
* Documentation for ~version~ | ||
|
||
Warning: This is bound to get out of date, so look at the documentation in the source. | ||
|
||
#+begin_src lisp :exports results | ||
(setf (cdr (assoc 'slynk:*string-elision-length* slynk:*slynk-pprint-bindings*)) nil) | ||
(documentation 'sijo-version:version 'function) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
#+begin_example | ||
Construct a semantic version (https://semver.org/) | ||
|
||
Note that minimal effort is made validating or sanitizing the input, so the user | ||
is able to construct an incorrect semantic version e.g. by supplying too many | ||
components to :VERSION. Some sanitizing is done by dropping invalid characters. | ||
|
||
Calling `version' will construct a default semantic version based on the VERSION | ||
file, ./.git/HEAD and the current time. | ||
|
||
If no VERSION file exists, the asdf components :VERSION will be used for the | ||
version number. | ||
|
||
If no version is found, 0.0.0 is used as the version. | ||
|
||
The VERSION file should contain the version number in the first line, and an | ||
optional pre-release tag in the second line. If no pre-release tag exist in the | ||
file, the default is to add the git branch name iff it's not the main/master | ||
branch. | ||
|
||
VERSION, PRE-RELEASE and BUILD-METADATA is evaluated by `%eval-spec' into a | ||
dotted string, and has the following semantics: | ||
- `string' :: use as-is - it's the canonical form | ||
- `list' ('or as first element) :: call `%eval-spec' on second element. If | ||
non-nil, return it, otherwise evaluate next element. If there are no more | ||
elements, return nil. | ||
- `list' ('and as first element) :: call `%eval-spec' on subsequent elements, | ||
remove nulls, and join with "-" as the separator. | ||
- `list' :: call `%eval-spec' on each element, remove nulls, and join with "." as a separator. | ||
- `function' :: call function pass result to `%eval-spec' | ||
- `symbol' :: if `fboundp', call function and pass result to `%eval-spec'. If | ||
`boundp' call `%eval-spec' on `symbol-value'. Otherwise call `%eval-spec' on | ||
the `symbol-name'. | ||
- `atom' :: convert to a string | ||
|
||
ROOT is the root folder where the VERSION file and .git directory is located. | ||
The value is evaluated by `%guess-root', and several different forms is | ||
accepted: | ||
- `pathname' :: use as-is - it's the canonical form | ||
- `asdf:system' :: `asdf:system-relative-pathname' is used as the root | ||
- `package' :: try to load a system with the same name as `package-name'. If no | ||
system is found, `*default-pathname-defaults*' is used. | ||
- `null' :: we guess given `*package*' instead | ||
- `string' :: try to load a system, if missing interpret the input as a `pathname' instead | ||
- `symbol' :: try to guess using the symbol as the system name | ||
|
||
Examples: | ||
|
||
`(version)' | ||
"0.1+main.748e8897a233ddbc26a959bd14a97acb0ef5b895.20240301152751Z" | ||
|
||
You can specify the system it should fetch information from directly using `:root' | ||
|
||
`(version :root :sijo-version)' | ||
"0.1+main.748e8897a233ddbc26a959bd14a97acb0ef5b895.20240301152751Z" | ||
|
||
You can remove the use of extra build metadata | ||
|
||
`(version :build-metadata nil)' | ||
"0.1-some-prerelease" | ||
|
||
You can specify the exact version and pre-release tag to use instead of looking in VERSION | ||
|
||
>> (version :version "0.1" :pre-release nil :build-metadata nil) | ||
"0.1" | ||
|
||
>> (version :version "0.1" :pre-release "pre" :build-metadata nil) | ||
"0.1-pre" | ||
|
||
>> (version :version "0.1" :pre-release nil :build-metadata "build") | ||
"0.1+build" | ||
|
||
>> (version :version "0.1" :pre-release "pre" :build-metadata "build") | ||
"0.1-pre+build" | ||
#+end_example | ||
|
||
* Troubleshooting | ||
** Component "some-package" not found | ||
~version~ tries to find out what the current system is by looking at | ||
~(package-name *package*)~. If you're calling ~version~ from a package not named | ||
the same as a system, it will fail. | ||
|
||
#+begin_src lisp :exports both :eval never | ||
(in-package :common-lisp-user) | ||
(sijo-version:version) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: Component "common-lisp-user" not found | ||
: [Condition of type ASDF/FIND-COMPONENT:MISSING-COMPONENT] | ||
|
||
In that case, you need to set ~:system~ yourself: | ||
|
||
#+begin_src lisp :exports both :eval never | ||
(in-package :common-lisp-user) | ||
(sijo-version:version :system :my-system) | ||
#+end_src | ||
|
||
#+RESULTS: | ||
: 0.1+main.7aeedb4d32927e19a5e9ed406ac5735db0fd20dd.20240301151319Z | ||
|
||
** Using =VERSION= in ~defsystem~ | ||
ASDF can read use the version from your =VERSION= file directly with the | ||
following syntax: | ||
|
||
#+begin_src lisp :eval never | ||
(defsystem :my-system | ||
;; ... | ||
:version (:read-file-line "VERSION" :at 0)) | ||
#+end_src | ||
|
||
* Versioning | ||
** =VERSION= file | ||
The file should include =major.minor.patch= on the first line, and an optional | ||
=prerelease= tag on the second line. | ||
|
||
** Build information | ||
The system assumes the project is using =git= by default, and will construct | ||
build information as follows: =branch.commit.timestamp= | ||
|
||
- =branch= is the current branch by reading =.git/HEAD= | ||
- =commit= is the current commit in =.git/HEAD= or by following the ref there | ||
- =timestamp= is a timestamp when calling the ~version~ function in the | ||
=yyyyMMddHHmmssZ= format |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
(defsystem :sijo-version | ||
:depends-on () | ||
:in-order-to ((test-op (test-op :sijo-version/tests))) | ||
:version (:read-file-line "VERSION" :at 0) | ||
:serial t | ||
:pathname "src/" | ||
:components ((:file "packages") | ||
(:file "sequence") | ||
(:file "version"))) | ||
|
||
(defsystem :sijo-version/tests | ||
:depends-on (#:sijo-version | ||
#:str | ||
#:lisp-unit2 | ||
#:sijo-doctest) | ||
:perform (test-op (o c) | ||
(eval (read-from-string " | ||
(lisp-unit2:with-summary () | ||
(lisp-unit2:run-tests | ||
:package :sijo-version/tests | ||
:name :sijo-version))"))) | ||
:serial t | ||
:pathname "tests/" | ||
:components ((:file "version"))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
(defpackage :sijo-version | ||
(:use #:cl) | ||
(:export #:version | ||
;; Helpers for constructing the semver | ||
#:version-file-line-0 | ||
#:version-file-line-1 | ||
#:system-version | ||
#:current-time | ||
#:git-non-main-branch | ||
#:git-current-branch | ||
#:git-current-commit)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
;; These functions is to avoid a dependency on the str library. | ||
|
||
(in-package :sijo-version) | ||
|
||
(defun split (needle haystack &aux result) | ||
(when (eql 0 (length needle)) | ||
(return-from split (list haystack))) | ||
(do ((pos (search needle haystack) (search needle haystack))) | ||
((null pos) (if haystack | ||
(nreverse (cons haystack result)) | ||
(nreverse result))) | ||
(setf result (cons (subseq haystack 0 pos) result)) | ||
(setf haystack (subseq haystack (+ pos (length needle)))))) | ||
|
||
(defun intersperse (separator seq &aux result) | ||
(do ((rest seq (subseq rest 1))) | ||
((or (null rest) (eql 0 (length rest))) (nreverse result)) | ||
(push (elt rest 0) result) | ||
(when (subseq rest 1) | ||
(push separator result)))) | ||
|
||
(defun concat (sequence) | ||
(let ((first (first sequence))) | ||
(typecase first | ||
(string (apply #'concatenate 'string sequence)) | ||
(array | ||
;; It might have a specific length, but we want a variable length as the result | ||
(apply #'concatenate (append (subseq (type-of first) 0 2) '((*))) sequence)) | ||
(t (apply #'concatenate (type-of first) sequence))))) | ||
|
||
(defun join (separator sequence) | ||
(concat (intersperse separator sequence))) | ||
|
||
(defun remove-all (needle haystack) | ||
(concat (split needle haystack))) | ||
|
||
(defun replace-all (old new haystack) | ||
(join new (split old haystack))) | ||
|
||
(defun starts-with (prefix string &key (test #'eql)) | ||
(eql 0 (search prefix string :test test :end2 (length prefix)))) | ||
|
||
(defun without-prefix (prefix string &key (test #'eql)) | ||
(if (starts-with prefix string :test test) | ||
(values (subseq string (length prefix)) t) | ||
(values string nil))) |
Oops, something went wrong.