From debbugs-submit-bounces@debbugs.gnu.org Mon Aug 04 17:37:52 2025 Received: (at submit) by debbugs.gnu.org; 4 Aug 2025 21:37:52 +0000 Received: from localhost ([127.0.0.1]:52861 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uj2sR-00058H-TX for submit@debbugs.gnu.org; Mon, 04 Aug 2025 17:37:52 -0400 Received: from lists.gnu.org ([2001:470:142::17]:52986) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uj2sM-00057p-Hv for submit@debbugs.gnu.org; Mon, 04 Aug 2025 17:37:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uj2sF-0003vE-Tk for bug-gnu-emacs@gnu.org; Mon, 04 Aug 2025 17:37:40 -0400 Received: from sender4-op-o10.zoho.com ([136.143.188.10]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uj2sC-0003Wj-Hr for bug-gnu-emacs@gnu.org; Mon, 04 Aug 2025 17:37:39 -0400 ARC-Seal: i=1; a=rsa-sha256; t=1754343419; cv=none; d=zohomail.com; s=zohoarc; b=E8vPRLBU0v1+zUbIlKk16Fe44erz+f0aP0uURc5g1SDENtk1eQOBMdrZj2YzwsWAY9U3RhhyN9URq8NDy0PktW54bBcNMjOR78ald4qDbgIQGTdTG/cqcGVaPpcIej4A1xLFUezX8fzo5ZjPjlynMDHYJoomvtWxFKLUm8g4Xu0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754343419; h=Content-Type:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=gCCas/ddMSIAwACcg3wx2qW7Sn6uCer81IsvTN25648=; b=ee4KB9r2dk/z8O8aun2sO9RM85dZBuhXbHYVUTUmfeseceFGAHobZgY/98UwL/ovQV40cM/0B2FgqE/a9sRyAdr6YwTZnvGY6aVvHywchdS8QXmfuUCtjdfLKbmD2Axa8aHeuF3826S4bKbkKKvQEN/NzLmOI6rX6V4B+KhzmTI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=antr.me; spf=pass smtp.mailfrom=mail@antr.me; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1754343419; s=zmail; d=antr.me; i=mail@antr.me; h=From:From:To:To:Subject:Subject:Date:Date:Message-ID:MIME-Version:Content-Type:Message-Id:Reply-To:Cc; bh=gCCas/ddMSIAwACcg3wx2qW7Sn6uCer81IsvTN25648=; b=g3WvNKVqmVoTBEJ/TRtDKxwBmpuHWRAjgEslkgErJPYKalDpzX3SYpbRZX4Z/epj AlxRIgyS5EhEoEGXLABBF98tJGao8PYH1thND5kAMaEQrf2XeY88vveBNdkgVgr0fiz dekh6i0ZMddUofx8WRma03Dsm0CWErqJTijt1B9U= Received: by mx.zohomail.com with SMTPS id 1754343416422643.1264788857887; Mon, 4 Aug 2025 14:36:56 -0700 (PDT) From: Antero Mejr To: bug-gnu-emacs@gnu.org Subject: [PATCH] Add SPDX support to copyright.el Date: Mon, 04 Aug 2025 21:36:54 +0000 Message-ID: <87pldan4zt.fsf@antr.me> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Zoho-Virus-Status: 1 X-Zoho-Virus-Status: 1 X-Zoho-AV-Stamp: zmail-av-1.4.3/254.317.26 X-ZohoMailClient: External Received-SPF: pass client-ip=136.143.188.10; envelope-from=mail@antr.me; helo=sender4-op-o10.zoho.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) --=-=-= Content-Type: text/plain Tags: patch This patch updates copyright.el to auto-insert SPDX- declarations. There is one new user-facing command 'copyright-spdx' and a few new customizable variables. It also makes the 'copyright' command use 'comment-add' so that the comment marker ;; is correct in Lisp modes, for both the SPDX and default formats. While working on this I also noticed the copyright skeletons in autoinsert.el are inconsistent - they have an extra space relative to those of copyright.el. IMO autoinsert.el should be adjusted to use the copyright.el code instead of reimplementing it. In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33, cairo version 1.16.0) of 2025-05-04 built on pop-os Repository revision: 159e3a981ed5482393182b036e38818d42405c90 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12101004 System Description: Pop!_OS 22.04 LTS --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Add-SPDX-support-to-copyright.el.patch Content-Transfer-Encoding: quoted-printable >From 8b630420d40e094ccd84f12ba0235c80f4c7a57f Mon Sep 17 00:00:00 2001 From: Antero Mejr Date: Mon, 4 Aug 2025 20:38:59 +0000 Subject: [PATCH] Add SPDX support to copyright.el * lisp/emacs-lisp/copyright.el (copyright): Use SPDX format if `copyright-spdx-enable' is t. (copyright): Respect `comment-add' variable and add space. (copyright-spdx): New autoloaded command. (copyright-spdx-insert): New procedure. (copyright-spdx-enable, copyright-spdx-filecopyrighttext-regexp, copyright-spdx-default-license): New custom-set variables. * etc/NEWS: Announce. * .dir-locals.el (nil): Set `copyright-spdx-enable' to nil. * doc/misc/autotype.texi (Copyrights): Mention SPDX command and variables. --- .dir-locals.el | 3 +- doc/misc/autotype.texi | 16 ++++++++ etc/NEWS | 17 +++++++++ lisp/emacs-lisp/copyright.el | 72 +++++++++++++++++++++++++++++++----- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/.dir-locals.el b/.dir-locals.el index af92eac5bba..bd43c3fc6e9 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -15,7 +15,8 @@ "/[ \t]*DEFVAR_[A-Z_ \t(]+\"[^\"]+\",[ \t]\\([A-Za-z0-9_]+\\)= /\\1/")))) (etags-regen-ignores . ("test/manual/etags/")) (vc-prepare-patches-separately . nil) - (vc-default-patch-addressee . "bug-gnu-emacs@gnu.org"))) + (vc-default-patch-addressee . "bug-gnu-emacs@gnu.org") + (copyright-spdx-enable . nil))) (c-mode . ((c-file-style . "GNU") (c-noise-macro-names . ("INLINE" "NO_INLINE" "ATTRIBUTE_NO_SAN= ITIZE_UNDEFINED" "ATTRIBUTE_NO_SANITIZE_ADDRESS" diff --git a/doc/misc/autotype.texi b/doc/misc/autotype.texi index c53be54d0af..1735952efec 100644 --- a/doc/misc/autotype.texi +++ b/doc/misc/autotype.texi @@ -385,6 +385,22 @@ Copyrights such as in the @code{before-save-hook} feature mentioned above. Otherwise you are always queried. =20 +@vindex copyright-spdx-enable + The variable @code{copyright-spdx-enable} controls whether to use the +@uref{https://spdx.dev/, SPDX} format when inserting copyright +declarations. When this variable is set to @code{t}, the +@code{SPDX-FileCopyrightText} declaration format will be used. + +@findex copyright-spdx +@vindex copyright-spdx-default-license + Some projects use the @code{SPDX-License-Identifier: } declaration at +the top of each source code file. The @code{copyright-spdx} command will +automatically insert that declaration, using the correct comment syntax +if applicable. If the variable @code{copyright-spdx-default-license} is +set, it will use that @uref{https://spdx.org/licenses/, SDPX license +identifier} to populate its field instead of prompting for an identifier +string. + =20 =20 @node Executables diff --git a/etc/NEWS b/etc/NEWS index e12a9dcb127..998cbe86b91 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -676,6 +676,23 @@ linefeeds". You can now use 'C-u C-x .' to clear the fill prefix, similarly to how you could already use 'C-u C-x C-n' to clear the goal column. =20 +** New command `copyright-spdx' and variable `copyright-spdx-enable' +The 'copyright-spdx' command inserts an "SPDX-License-Identifier" at +point. If 'copyright-spdx-default-license' is set, it will autofill with +its value, otherwise it will prompt for a license identifier string. + +The `copyright-spdx-enable' variable, if set to t, indicates that the +'copyright' command should use the "SPDX-FileCopyrightText: " format. + ++++ +** 'copyright' command now respects 'comment-add' +Previously, the 'copyright' command would insert a single comment mark +and no additional spaces, even when 'comment-add' was non-zero (such as +in lisp-derived modes). Now 'copyright' will insert the correct number +of comment marks along with a space, so that the text is correctly +formatted. + +--- * Changes in Specialized Modes and Packages in Emacs 31.1 =20 diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el index 59a2b166a9d..9eb404cec72 100644 --- a/lisp/emacs-lisp/copyright.el +++ b/lisp/emacs-lisp/copyright.el @@ -144,7 +144,9 @@ copyright-find-copyright (with-demoted-errors "Can't update copyright: %s" ;; (1) Need the extra \\( \\) around copyright-regexp because we ;; goto (match-end 1) below. See note (2) below. - (let ((regexp (concat "\\(" copyright-regexp + (let ((regexp (concat "\\(" (if copyright-spdx-enable + copyright-spdx-filecopyrighttext-regexp + copyright-regexp) "\\)\\([ \t]*\n\\)?.*\\(?:" copyright-names-regexp "\\)"))) (when (copyright-re-search regexp (copyright-limit) t) @@ -343,16 +345,27 @@ copyright-fix-years (message "No copyright message"))) =20 ;;;###autoload -(define-skeleton copyright +(defun copyright () "Insert a copyright by $ORGANIZATION notice at cursor." - "Company: " - comment-start - "Copyright (C) " `(format-time-string "%Y") " by " - (or (getenv "ORGANIZATION") - str) - '(if (copyright-offset-too-large-p) - (message "Copyright extends beyond `copyright-limit' and won't be u= pdated automatically.")) - comment-end \n) + (interactive) + (let ((org (or (getenv "ORGANIZATION") + (read-string "Company: ")))) + (if copyright-spdx-enable + (copyright-spdx-insert org) + (copyright-insert org)))) + +(defun copyright-comment-start () + "Get a comment-start string repeated the correct number of times." + (apply #'concat (mapcar (lambda (x) + comment-start) + (number-sequence 0 comment-add)))) + +(defun copyright-insert (org) + (insert (copyright-comment-start) + " Copyright (C) " (format-time-string "%Y") " by " org + comment-end "\n") + (when (copyright-offset-too-large-p) + (message "Copyright extends beyond `copyright-limit' and won't be upda= ted automatically."))) =20 ;; TODO: recurse, exclude COPYING etc. ;;;###autoload @@ -374,6 +387,45 @@ copyright-update-directory (save-buffer) (kill-buffer (current-buffer))))) =20 +;; SPDX features + +;; TODO: It may be possible to accurately infer SPDX usage. +(defcustom copyright-spdx-enable nil + "Non-nil means copyright notices are expected to be in SPDX format." + :type 'boolean + :safe #'booleanp) + +(defcustom copyright-spdx-filecopyrighttext-regexp + "\\(SPDX-FileCopyrightText\\s *:?\\s *\\(?:(C)\\)?\ +\\|SPDX-FileCopyrightText\\s *:?\\s *=C2=A9\\)\ +\\s *[^0-9\n]*\\s *\ +\\([1-9]\\([-0-9, ';/*%#\n\t=E2=80=93]\\|\\s<\\|\\s>\\)*[0-9]+\\)" + "Regex to find the SPDX-FileCopyrightText: declaration" + :type 'regexp + :safe 'stringp) + +(defcustom copyright-spdx-default-license nil + "If non-nil, specify SPDX-License-Identifier to use by default." + :type 'stringp + :safe 'stringp) + +;;;###autoload +(defun copyright-spdx (&optional identifier) + "Insert an SPDX-License-Identifier: at cursor. +Will prompt unless `copyright-spdx-default-license' is set." + (interactive + (list (or copyright-spdx-default-license + (read-string "SPDX License Identifier: ")))) + (insert (copyright-comment-start) " SPDX-License-Identifier: " + identifier comment-end "\n")) + +(defun copyright-spdx-insert (org) + "Insert an SPDX-FileCopyrightText: declaration." + (insert (copyright-comment-start) " SPDX-FileCopyrightText: " + (format-time-string "%Y") " " org comment-end "\n") + (when (copyright-offset-too-large-p) + (message "Copyright extends beyond `copyright-limit' and won't be upda= ted automatically."))) + (provide 'copyright) =20 ;;; copyright.el ends here --=20 2.34.1 --=-=-=--