Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how

* Add command to generate LICENSE file (#155)
* Add new DSLs `author` and `license` (#156)
* Add license linter (#157)

## 0.8.x
> Released Mar 08, 2023
Expand Down
2 changes: 1 addition & 1 deletion cmds/lint/keywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"use strict";

exports.command = ['keywords'];
exports.desc = `Lint the package's keywords header`;
exports.desc = `Run keywords checker (built-in)`;

exports.handler = async (argv) => {
await UTIL.e_call(argv, 'lint/keywords');
Expand Down
27 changes: 27 additions & 0 deletions cmds/lint/license.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (C) 2023 Jen-Chieh Shen
*
* 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, 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 GNU Emacs; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

"use strict";

exports.command = ['license'];
exports.desc = `Run license check`;

exports.handler = async (argv) => {
await UTIL.e_call(argv, 'lint/license');
};
8 changes: 8 additions & 0 deletions docs/content/en/Getting Started/Commands and options.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,14 @@ Run keywords checker (built-in).
$ eask [GLOBAL-OPTIONS] lint keywords
```

## 🔍 eask lint license

Run license check.

```sh
$ eask [GLOBAL-OPTIONS] lint license
```

## 🔍 eask lint declare

Run check-declare (built-in).
Expand Down
107 changes: 107 additions & 0 deletions lisp/lint/license.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
;;; lint/license.el --- Lint the package's license -*- lexical-binding: t; -*-

;;; Commentary:
;;
;; Command use to check license for the package,
;;
;; $ eask lint license
;;

;;; Code:

(let ((dir (file-name-directory (nth 1 (member "-scriptload" command-line-args)))))
(load (expand-file-name "_prepare.el"
(locate-dominating-file dir "_prepare.el"))
nil t))

;;
;;; Flags

(advice-add #'eask-allow-error-p :override (lambda (&rest _) t))

;;
;;; Core

(defun eask--string-match-all (regexps)
"Return t when every REGEXPS match the `buffer-string'."
(cl-every (lambda (regexp)
(string-match-p regexp (buffer-string)))
regexps))

(defun eask--scan-license (file)
"Scan the license FILE."
(with-current-buffer (find-file file)
;; See https://api.github.com/licenses
(cond
((eask--string-match-all '("GNU AFFERO GENERAL PUBLIC LICENSE"
"Version 3"
"You should have received a copy of the GNU Affero General Public License"))
'("agpl-3.0" "GNU Affero General Public License v3.0" "AGPL-3.0"))
((eask--string-match-all '("Apache"
"http://www.apache.org/licenses/"))
'("apache-2.0" "Apache License 2.0" "Apache-2.0"))
((eask--string-match-all '("BSD 2-Clause"))
'("bsd-2-clause" "BSD 2-Clause \"Simplified\" License" "BSD-2-Clause"))
((eask--string-match-all '("BSD 3-Clause"))
'("bsd-3-clause" "BSD 3-Clause \"New\" or \"Revised\" License" "BSD-3-Clause"))
((eask--string-match-all '("Boost Software License - Version 1.0"))
'("bsl-1.0" "Boost Software License 1.0" "BSL-1.0"))
((eask--string-match-all '("CC0 1.0"))
'("cc0-1.0" "Creative Commons Zero v1.0 Universal" "CC0-1.0"))
((eask--string-match-all '("Eclipse Public License - v 2.0"
"Eclipse Foundation"))
'("epl-2.0" "Eclipse Public License 2.0" "EPL-2.0"))
((eask--string-match-all '("GNU General Public License"
"Version 2"))
'("gpl-2.0" "GNU General Public License v2.0" "GPL-2.0"))
((eask--string-match-all '("GNU General Public License"
"version 3"
"You should have received a copy of the GNU General Public License"))
'("gpl-3.0" "GNU General Public License v3.0" "GPL-3.0"))
((eask--string-match-all '("Lesser GPL"
"Version 2.1"))
'("lgpl-2.1" "GNU Lesser General Public License v2.1" "LGPL-2.1"))
((eask--string-match-all '("Permission is hereby granted, free of charge, to any person obtaining a copy"))
'("mit" "MIT License" "MIT"))
((eask--string-match-all '("Mozilla Public License Version 2.0"
"http://mozilla.org/MPL/2.0/"))
'("mpl-2.0" "Mozilla Public License 2.0" "MPL-2.0"))
((eask--string-match-all '("This is free and unencumbered software released into the public domain"
"https://unlicense.org"))
'("unlicense" "The Unlicense" "Unlicense"))
(t
'("unknown" "Unknown license" "unknown")))))

(defun eask--print-scanned-license (scanned)
"Print all SCANNED license."
(eask-msg "available via `eask lint license`")
(eask-msg "")
(let* ((names (mapcar #'car scanned))
(offset (eask-seq-str-max names))
(fmt (concat " %-" (eask-2str offset) "s %s")))
(dolist (data scanned)
(eask-msg fmt (nth 0 data) (nth 3 data)))
(eask-msg "")
(eask-info "(Total of %s scanned license%s)" (length names)
(eask--sinr names "" "s"))))
(eask-start
(let* ((license-names '("copying" "copying.txt"
"license" "license.txt" "license.md"
"unlicense"))
(files (eask-expand-file-specs license-names))
(scanned))
(cond
((null files)
(eask-info "✗ No license found"))
(t
(when (<= 2 (length files))
(eask-warn "!! Multi-licensing detected !!"))

(eask-progress-seq " - Sanning" files "done! ✓"
(lambda (file)
(push (append (eask--scan-license file) `(,file)) scanned)))

(eask-msg "")
(eask--print-scanned-license (reverse scanned))))))

;;; lint/license.el ends here
1 change: 1 addition & 0 deletions test/commands/local/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ eask lint elisp-lint
#eask lint elsa # XXX: Elsa is not stable, ignore it for now
eask lint indent
eask lint keywords
eask lint license
eask lint package
eask lint regexps

Expand Down