Enhance: Add more translations, remove unused ones and add linter for unused (#8568)

* chore: remove unused dictionary keys

* wip: add dictionary keys for hardcoded strings

* resolve conflicts

* Add linter to detect :en ui translation keys match used ones

- Fix a couple entries caught by linter
- Copy :command.editor/open-link-in-sidebar entries to
  :help/open-link-in-sidebar as translation keys shouldn't be reused in
  multiple contexts, especially when it's across ui and shortcut dicts

* fix: remove dead keys

* chore: reuse dict keys

* chore: reintroduce useful keys

---------

Co-authored-by: Gabriel Horner <gabriel@logseq.com>
This commit is contained in:
Konstantinos
2023-02-24 16:21:57 +02:00
committed by GitHub
parent ec157b8f2c
commit 2cace8894c
15 changed files with 145 additions and 1539 deletions

View File

@@ -16,7 +16,7 @@
(doseq [cmd ["clojure -M:clj-kondo --parallel --lint src --cache false"
"bb lint:carve"
"bb lint:large-vars"
"bb lang:invalid-translations"
"bb lang:validate-translations"
"bb lint:ns-docstrings"]]
(println cmd)
(shell cmd)))

View File

@@ -1,9 +1,11 @@
(ns logseq.tasks.lang
"Tasks related to language translations"
(:require [clojure.set :as set]
[clojure.string :as string]
[frontend.dicts :as dicts]
[frontend.modules.shortcut.dicts :as shortcut-dicts]
[logseq.tasks.util :as task-util]))
[logseq.tasks.util :as task-util]
[babashka.process :refer [shell]]))
(defn- get-dicts
[]
@@ -69,8 +71,11 @@
(sort-by (juxt :file :translation-key))
task-util/print-table))))
(defn invalid-translations
"Lists translation that don't exist in English"
(defn- validate-non-default-languages
"This validation finds any translation keys that don't exist in the default
language English. Logseq needs to work out of the box with its default
language. This catches mistakes where another language has accidentally typoed
keys or added ones without updating :en"
[]
(let [dicts (get-all-dicts)
;; For now defined as :en but clj-kondo analysis could be more thorough
@@ -83,12 +88,68 @@
(set/difference (set (keys get-dicts))
valid-keys)))))]
(if (empty? invalid-dicts)
(println "All translations have valid keys!")
(println "All non-default translations have valid keys!")
(do
(println "Invalid translation keys found:")
(println "\nThese translation keys are invalid because they don't exist in English:")
(task-util/print-table invalid-dicts)
(System/exit 1)))))
;; Command to check for manual entries:
;; grep -E -oh '\(t [^ ):]+' -r src/main
(def manual-ui-dicts
"Manual list of ui translations because they are dynamic i.e. keyword isn't
first arg. Only map values are used in linter as keys are for easily scanning
grep result."
{"(t (shortcut-helper/decorate-namespace" [] ;; shortcuts related so can ignore
"(t (keyword" [:color/yellow :color/red :color/pink :color/green :color/blue
:color/purple :color/gray]
;; from 3 files
"(t (if" [:asset/show-in-folder :asset/open-in-browser
:search-item/whiteboard :search-item/page
:page/make-private :page/make-public]
"(t (name" [] ;; shortcuts related
"(t (dh/decorate-namespace" [] ;; shortcuts related
"(t prompt-key" [:select/default-prompt :select.graph/prompt]
;; All args to ui/make-confirm-modal are not keywords
"(t title" []
"(t subtitle" [:asset/physical-delete]})
(defn- validate-ui-translations-are-used
"This validation checks to see that translations done by (t ...) are equal to
the ones defined for the default :en lang. This catches translations that have
been added in UI but don't have an entry or translations no longer used in the UI"
[]
(let [actual-dicts (->> (shell {:out :string}
;; This currently assumes all ui translations
;; use (t and src/main. This can easily be
;; tweaked as needed
"grep -E -oh '\\(t :[^ )]+' -r src/main")
:out
string/split-lines
(map #(keyword (subs % 4)))
(concat (mapcat val manual-ui-dicts))
set)
expected-dicts (set (keys (:en (get-dicts))))
actual-only (set/difference actual-dicts expected-dicts)
expected-only (set/difference expected-dicts actual-dicts)]
(if (and (empty? actual-only) (empty? expected-only))
(println "All defined :en translation keys match the ones that are used!")
(do
(when (seq actual-only)
(println "\nThese translation keys are invalid because they are used in the UI but not defined:")
(task-util/print-table (map #(hash-map :invalid-key %) actual-only)))
(when (seq expected-only)
(println "\nThese translation keys are invalid because they are not used in the UI:")
(task-util/print-table (map #(hash-map :invalid-key %) expected-only)))
(System/exit 1)))))
(defn validate-translations
"Runs multiple translation validations that fail fast if one of them is invalid"
[]
(validate-non-default-languages)
(validate-ui-translations-are-used))
(defn list-duplicates
"Lists translations that are the same as the one in English"
[& args]