From bd91e07e8770bb70ab0991fb4fb07a0d337d4297 Mon Sep 17 00:00:00 2001 From: JenChieh Date: Mon, 30 Jun 2025 06:30:32 -0700 Subject: [PATCH 1/3] feat: Add command for org-lint --- cmds/lint/org.js | 31 ++++++++ .../Commands-and-options/_index.en.md | 34 ++++---- .../Commands-and-options/_index.zh-tw.md | 38 +++++---- lisp/help/lint/org | 8 ++ lisp/lint/org.el | 78 +++++++++++++++++++ test/jest/local.test.js | 8 ++ test/jest/local/Eask | 2 +- test/jest/local/README.org | 19 +++++ test/jest/local/mini.pkg.1.el | 2 +- 9 files changed, 190 insertions(+), 30 deletions(-) create mode 100644 cmds/lint/org.js create mode 100644 lisp/help/lint/org create mode 100644 lisp/lint/org.el create mode 100644 test/jest/local/README.org diff --git a/cmds/lint/org.js b/cmds/lint/org.js new file mode 100644 index 00000000..9f0da30e --- /dev/null +++ b/cmds/lint/org.js @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2025 the Eask authors. + * + * 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 this program. If not, see . + */ + +"use strict"; + +exports.command = ['org [files..]']; +exports.desc = `Run org-lint on Org files`; +exports.builder = yargs => yargs + .positional( + '[files..]', { + description: 'files you want org-lint to run on', + type: 'array', + }); + +exports.handler = async (argv) => { + await UTIL.e_call(argv, 'lint/org', argv.files); +}; diff --git a/docs/content/Getting-Started/Commands-and-options/_index.en.md b/docs/content/Getting-Started/Commands-and-options/_index.en.md index 3bc6cb6e..3ec1a6f8 100644 --- a/docs/content/Getting-Started/Commands-and-options/_index.en.md +++ b/docs/content/Getting-Started/Commands-and-options/_index.en.md @@ -808,38 +808,46 @@ Run indent-lint. eask [GLOBAL-OPTIONS] lint indent [FILES..] ``` -## πŸ” eask lint keywords +## πŸ” eask lint declare -Run keywords checker (built-in). +Run check-declare (built-in). ```sh -eask [GLOBAL-OPTIONS] lint keywords +eask [GLOBAL-OPTIONS] lint declare [FILES..] ``` -## πŸ” eask lint license +## πŸ” eask lint regexps -Run license check. +Run [relint](https://github.com/mattiase/relint). + +Alias: `lint relint` ```sh -eask [GLOBAL-OPTIONS] lint license +eask [GLOBAL-OPTIONS] lint regexps [FILES..] ``` -## πŸ” eask lint declare +## πŸ” eask lint keywords -Run check-declare (built-in). +Run keywords checker (built-in). ```sh -eask [GLOBAL-OPTIONS] lint declare [FILES..] +eask [GLOBAL-OPTIONS] lint keywords ``` -## πŸ” eask lint regexps +## πŸ” eask lint license -Run [relint](https://github.com/mattiase/relint). +Run license check. -Alias: `lint relint` +```sh +eask [GLOBAL-OPTIONS] lint license +``` + +## πŸ” eask lint org + +Run `org-lint` on Org files. ```sh -eask [GLOBAL-OPTIONS] lint regexps [FILES..] +eask [GLOBAL-OPTIONS] lint org ``` # 🚩 Testing diff --git a/docs/content/Getting-Started/Commands-and-options/_index.zh-tw.md b/docs/content/Getting-Started/Commands-and-options/_index.zh-tw.md index 60a023ee..da15bd13 100644 --- a/docs/content/Getting-Started/Commands-and-options/_index.zh-tw.md +++ b/docs/content/Getting-Started/Commands-and-options/_index.zh-tw.md @@ -754,7 +754,7 @@ eask [GLOBAL-OPTIONS] lint package [FILES..] ## πŸ” eask lint checkdoc -ι‹θ‘Œ checkdoc (θ‡ͺεΈΆ). +ι‹θ‘Œ checkdoc (θ‡ͺεΈΆ)。 ```sh eask [GLOBAL-OPTIONS] lint checkdoc [FILES..] @@ -762,7 +762,7 @@ eask [GLOBAL-OPTIONS] lint checkdoc [FILES..] ## πŸ” eask lint elint -ι‹θ‘Œ elint (θ‡ͺεΈΆ). +ι‹θ‘Œ elint (θ‡ͺεΈΆ)。 ```sh eask [GLOBAL-OPTIONS] lint elint [FILES..] @@ -794,38 +794,46 @@ eask [GLOBAL-OPTIONS] lint lint elsa [FILES..] eask [GLOBAL-OPTIONS] lint indent [FILES..] ``` -## πŸ” eask lint keywords +## πŸ” eask lint declare -ι‹θ‘Œ keywords checker (θ‡ͺεΈΆ). +ι‹θ‘Œ check-declare (θ‡ͺεΈΆ)。 ```sh -eask [GLOBAL-OPTIONS] lint keywords +eask [GLOBAL-OPTIONS] lint declare [FILES..] ``` -## πŸ” eask lint license +## πŸ” eask lint regexps -ι‹θ‘Œ license check. +Run [relint](https://github.com/mattiase/relint). + +εˆ₯名: `lint relint` ```sh -eask [GLOBAL-OPTIONS] lint license +eask [GLOBAL-OPTIONS] lint regexps [FILES..] ``` -## πŸ” eask lint declare +## πŸ” eask lint keywords -ι‹θ‘Œ check-declare (θ‡ͺεΈΆ). +ι‹θ‘Œ keywords checker (θ‡ͺεΈΆ). ```sh -eask [GLOBAL-OPTIONS] lint declare [FILES..] +eask [GLOBAL-OPTIONS] lint keywords ``` -## πŸ” eask lint regexps +## πŸ” eask lint license -Run [relint](https://github.com/mattiase/relint). +ι‹θ‘Œ license ζͺ’ζŸ₯器。 -εˆ₯名: `lint relint` +```sh +eask [GLOBAL-OPTIONS] lint license +``` + +## πŸ” eask lint org + +在 Org ζͺ”ζ‘ˆδΈŠι‹θ‘Œ `org-lint`。 ```sh -eask [GLOBAL-OPTIONS] lint regexps [FILES..] +eask [GLOBAL-OPTIONS] lint org ``` # 🚩 ζΈ¬θ©¦ζ‘†ζžΆ diff --git a/lisp/help/lint/org b/lisp/help/lint/org new file mode 100644 index 00000000..068fc891 --- /dev/null +++ b/lisp/help/lint/org @@ -0,0 +1,8 @@ + +πŸ’‘ You need to specify pattern(s) you want to check + + $ eask lint org [FILES..] + +For example, + + $ eask lint org README.org docs/*.org diff --git a/lisp/lint/org.el b/lisp/lint/org.el new file mode 100644 index 00000000..583f5fc6 --- /dev/null +++ b/lisp/lint/org.el @@ -0,0 +1,78 @@ +;;; lint/org.el --- Run org-lint on Org files -*- lexical-binding: t; -*- + +;;; Commentary: +;; +;; Commmand use to run `org-lint' for all files +;; +;; $ eask lint org [files..] +;; +;; +;; Positionals: +;; +;; [files..] files you want org-lint to run on +;; + +;;; 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 #'eask-always) + +;; +;;; Core + +(defun eask-lint-org--print-error (file result) + "Print the error RESULT from FILE." + (let* ((data (cl-second result)) + (filename (file-name-nondirectory file)) + (line (elt data 0)) + (text (elt data 2)) + (msg (concat filename ":" line ": " text))) + (if (eask-strict-p) (error msg) (warn msg)))) + +(defun eask-lint-org--file (file) + "Run `org-lint' on FILE." + (eask-msg "`%s` with org-lint" (ansi-green file)) + (with-temp-buffer + (insert-file-contents file) + (org-mode) + (if-let* ((results (org-lint))) + (mapc (lambda (result) + (eask-lint-org--print-error file result)) + results) + (eask-msg "No issues found")))) + +(eask-start + ;; Preparation + (eask-archive-install-packages '("gnu") + 'org) + + ;; Start Linting + (require 'org-lint) + (let* ((patterns (eask-args)) + (files (eask-expand-file-specs patterns))) + (cond + ;; Files found, do the action! + (files + (mapcar #'eask-lint-org--file files) + (eask-msg "") + (eask-info "(Total of %s file%s linted)" (length files) + (eask--sinr files "" "s"))) + ;; Pattern defined, but no file found! + (patterns + (eask-msg "") + (eask-info "(No files match wildcard: %s)" + (mapconcat #'identity patterns " "))) + ;; Default, print help! + (t + (eask-msg "") + (eask-info "(No files have been linted)") + (eask-help "lint/org"))))) + +;;; lint/org.el ends here diff --git a/test/jest/local.test.js b/test/jest/local.test.js index 32100073..b6657c5e 100644 --- a/test/jest/local.test.js +++ b/test/jest/local.test.js @@ -198,6 +198,7 @@ describe("local", () => { describe("Linting", () => { // some lint commands may fail if packages are missing beforeAll(async () => await ctx.runEask("install-deps")); + it.each([ "lint checkdoc", "lint declare", @@ -207,18 +208,25 @@ describe("local", () => { "lint keywords", "lint license", "lint package", + "lint org", ])("eask %s", async (cmd) => { await ctx.runEask(cmd); }); + it("lint regexps", async () => { if ((await emacsVersion()) >= "27.1") { await ctx.runEask("lint regexps"); } }); + // XXX: Elsa is not stable, ignore it for now test.skip("lint elsa", async () => { await ctx.runEask("lint elsa"); }); + + it("lint org *.org", async () => { + await ctx.runEask("lint org *.org"); + }); }); describe("Testing", () => { diff --git a/test/jest/local/Eask b/test/jest/local/Eask index 10e9b56f..a5735287 100644 --- a/test/jest/local/Eask +++ b/test/jest/local/Eask @@ -1,7 +1,7 @@ ;; -*- mode: eask; lexical-binding: t -*- (package "mini.pkg.1" - "5.5.6" + "7.7.8" "Minimal test package") (website-url "https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1") diff --git a/test/jest/local/README.org b/test/jest/local/README.org new file mode 100644 index 00000000..ab5c45c0 --- /dev/null +++ b/test/jest/local/README.org @@ -0,0 +1,19 @@ +* Test Org File +This is a test org file used for Emacs behavior checking. + +** TODO Broken heading without space +***BROKEN Heading + +** Code Block +#+BEGIN_SRC emacs-lisp +(message "Hello, Emacs!") +(1+ ) ; Intentional syntax error +#+END_SRC + +** Bad Property +:PROPERTIES: +:WRONGPROP without value +:END: + +** Notes +Unclosed *bold and /italic text. diff --git a/test/jest/local/mini.pkg.1.el b/test/jest/local/mini.pkg.1.el index 5438f83c..6f729635 100644 --- a/test/jest/local/mini.pkg.1.el +++ b/test/jest/local/mini.pkg.1.el @@ -5,7 +5,7 @@ ;; Author: Shen, Jen-Chieh ;; URL: https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1 -;; Version: 5.5.6 +;; Version: 7.7.8 ;; Package-Requires: ((emacs "24.3") (s "1.12.0") (fringe-helper "1.0.1")) ;; Keywords: test local From d37e10365a93f00befc19140b57681933d7df11e Mon Sep 17 00:00:00 2001 From: JenChieh Date: Mon, 30 Jun 2025 06:31:50 -0700 Subject: [PATCH 2/3] split org lint to its own test --- test/jest/local.test.js | 1 - test/jest/local/Eask | 2 +- test/jest/local/mini.pkg.1.el | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/jest/local.test.js b/test/jest/local.test.js index b6657c5e..5803c0ae 100644 --- a/test/jest/local.test.js +++ b/test/jest/local.test.js @@ -208,7 +208,6 @@ describe("local", () => { "lint keywords", "lint license", "lint package", - "lint org", ])("eask %s", async (cmd) => { await ctx.runEask(cmd); }); diff --git a/test/jest/local/Eask b/test/jest/local/Eask index a5735287..6dc8cced 100644 --- a/test/jest/local/Eask +++ b/test/jest/local/Eask @@ -1,7 +1,7 @@ ;; -*- mode: eask; lexical-binding: t -*- (package "mini.pkg.1" - "7.7.8" + "8.8.9" "Minimal test package") (website-url "https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1") diff --git a/test/jest/local/mini.pkg.1.el b/test/jest/local/mini.pkg.1.el index 6f729635..542f62b3 100644 --- a/test/jest/local/mini.pkg.1.el +++ b/test/jest/local/mini.pkg.1.el @@ -5,7 +5,7 @@ ;; Author: Shen, Jen-Chieh ;; URL: https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1 -;; Version: 7.7.8 +;; Version: 8.8.9 ;; Package-Requires: ((emacs "24.3") (s "1.12.0") (fringe-helper "1.0.1")) ;; Keywords: test local From 7c56438535e74c6efa550220ba5a1e253ffdcc16 Mon Sep 17 00:00:00 2001 From: JenChieh Date: Mon, 30 Jun 2025 06:35:59 -0700 Subject: [PATCH 3/3] chore: changelog --- CHANGELOG.md | 1 + test/jest/local/Eask | 2 +- test/jest/local/mini.pkg.1.el | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 592b1fb1..927c0752 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how * fix(lisp/extern): Clean up `compat` (2b41f5db4b5bbe145c9671f95850f79a00dcbd48) * fix(lisp): Paint keywords with nested ansi codes (#323) * feat(create): Add new command for `el-project` (#325) +* feat(lint): Add command for `org-lint` (#328) ## 0.11.x > Released Apr 03, 2025 diff --git a/test/jest/local/Eask b/test/jest/local/Eask index 6dc8cced..91d8bb6d 100644 --- a/test/jest/local/Eask +++ b/test/jest/local/Eask @@ -1,7 +1,7 @@ ;; -*- mode: eask; lexical-binding: t -*- (package "mini.pkg.1" - "8.8.9" + "9.9.10" "Minimal test package") (website-url "https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1") diff --git a/test/jest/local/mini.pkg.1.el b/test/jest/local/mini.pkg.1.el index 542f62b3..fd474bcc 100644 --- a/test/jest/local/mini.pkg.1.el +++ b/test/jest/local/mini.pkg.1.el @@ -5,7 +5,7 @@ ;; Author: Shen, Jen-Chieh ;; URL: https://github.com/emacs-eask/cli/tree/master/test/fixtures/mini.pkg.1 -;; Version: 8.8.9 +;; Version: 9.9.10 ;; Package-Requires: ((emacs "24.3") (s "1.12.0") (fringe-helper "1.0.1")) ;; Keywords: test local