Skip to content

Instantly share code, notes, and snippets.

@progfolio
Created February 23, 2024 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save progfolio/2e95b1e3ba53116a40b01a08be20a26e to your computer and use it in GitHub Desktop.
Save progfolio/2e95b1e3ba53116a40b01a08be20a26e to your computer and use it in GitHub Desktop.
semver.el MELPA review
;;; semver.el --- Semver interpreter for Emacs -*- lexical-binding: t; -*-
;; Copyright (C) 2024 Guillaume Pasquet
;; Author: Guillaume Pasquet <dev@etenil.net>
;; Keywords: semver helper development
;; X-URL: https://gitlab.com/binary-ec/semver.el
;; URL: https://gitlab.com/binary-ec/semver.el
;; This file is not a part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Semver is a simple library to help you interpret semver version constraints
;;; Usage:
;; Load the file with `(require 'semver)' and then use the functions
;; `semver--expand' or `semver--expand-at-point' to expand a semver
;; spec to a more explicit version constraint.
;;; Contributing:
;; Please feel free to send PRs for any improvements or bug fixes.
;;; Code:
(defvar semver-constraint-prefixes '("^" "~" ">" "<=" ">=" "<" "=")
"List of constraint prefix strings.")
(defvar semver-constraint-regexp
(regexp-opt semver-constraint-prefixes "\\`\\(")
"Regexp matching a constraint prefix.")
(defvar semver-version-regexp "\\([0-9]+\\)\\.\\([0-9]+\\)\\.\\([0-9]+\\)"
"Regexp matching MAJOR MINOR PATCH triplet.")
(defun semver-constraint (spec)
"Return constraint portion of SPEC string."
(and (string-match semver-constraint-regexp spec) (match-string 1 spec)))
(defun semver-version (spec)
"Return list of form (MAJOR MINOR PATCH) from SPEC string."
(when (string-match (concat semver-constraint-regexp "*" semver-version-regexp)
spec)
(mapcar (lambda (i) (string-to-number (match-string i spec))) '(2 3 4))))
(defun semver--format (version &optional constraint)
"Return expanded VERSION CONSTRAINT string.
CONSTRAINT must be a member of `semver-constraint-prefixes'.
VERSION must be a list as returned by `semver-version'."
(apply (cond ((equal constraint "^")
(lambda (_ major minor patch)
(format ">=%d.%d.%d <%d.0.0" major minor patch (1+ major))))
((equal constraint "~")
(lambda (_ major minor patch)
(format ">=%d.%d.%d <%d.%d.0" major minor patch major (1+ minor))))
(t (lambda (constraint major minor patch)
(format "%s%d.%d.%d" constraint major minor patch))))
(cons (or constraint "") version)))
(defun semver-expand (spec &optional message)
"Return expanded SPEC string.
If MESSAGE is non-nil, or called interacively, `message' result."
(interactive (list (read-string "semver spec: "
(when-let ((s (thing-at-point 'string)))
(substring s 1 -1))) ;; Drop quotes.
t))
(let ((result (semver--format (or (semver-version spec)
(user-error "Invalid semver string"))
(semver-constraint spec))))
(when message (message "%s" result))
result))
(provide 'semver)
;;; semver.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment