Add a CI check for `todo!` and `FIXME` comments (#21950)

Michael Sloan created

Motivation for this is to support writing comments that will certainly
be revisited before merge.

Release Notes:

- N/A

Change summary

.github/workflows/ci.yml                                     |  4 ++
crates/collab/k8s/collab.template.yml                        |  2 
crates/file_icons/src/file_icons.rs                          |  4 +-
crates/gpui/src/platform/windows/clipboard.rs                |  2 
crates/markdown/examples/markdown.rs                         |  2 
crates/project/src/buffer_store.rs                           |  2 
crates/project/src/lsp_store.rs                              |  2 
crates/repl/src/notebook/notebook_ui.rs                      |  2 
crates/repl/src/outputs/markdown.rs                          |  2 
crates/repl/src/session.rs                                   |  2 
crates/zed/src/zed/quick_action_bar/repl_menu.rs             |  2 
docs/theme/css/chrome.css                                    |  2 
extensions/terraform/languages/terraform-vars/highlights.scm |  2 
extensions/terraform/languages/terraform/highlights.scm      |  2 
script/check-todos                                           | 11 ++++++
15 files changed, 29 insertions(+), 14 deletions(-)

Detailed changes

.github/workflows/ci.yml πŸ”—

@@ -94,6 +94,10 @@ jobs:
       - name: Checkout repo
         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
 
+      # To support writing comments that they will certainly be revisited.
+      - name: Check for todo​! and FIX​ME comments
+        run: script/check-todos
+
       - name: Run style checks
         uses: ./.github/actions/check_style
 

crates/collab/k8s/collab.template.yml πŸ”—

@@ -252,7 +252,7 @@ spec:
               value: "${AUTO_JOIN_CHANNEL_ID}"
           securityContext:
             capabilities:
-              # FIXME - Switch to the more restrictive `PERFMON` capability.
+              # TODO - Switch to the more restrictive `PERFMON` capability.
               # This capability isn't yet available in a stable version of Debian.
               add: ["SYS_ADMIN"]
       terminationGracePeriodSeconds: 10

crates/file_icons/src/file_icons.rs πŸ”—

@@ -51,8 +51,8 @@ impl FileIcons {
     pub fn get_icon(path: &Path, cx: &AppContext) -> Option<SharedString> {
         let this = cx.try_global::<Self>()?;
 
-        // FIXME: Associate a type with the languages and have the file's language
-        //        override these associations
+        // TODO: Associate a type with the languages and have the file's language
+        //       override these associations
         maybe!({
             let suffix = path.icon_stem_or_suffix()?;
 

crates/gpui/src/platform/windows/clipboard.rs πŸ”—

@@ -357,7 +357,7 @@ impl From<ImageFormat> for image::ImageFormat {
             ImageFormat::Jpeg => image::ImageFormat::Jpeg,
             ImageFormat::Webp => image::ImageFormat::WebP,
             ImageFormat::Gif => image::ImageFormat::Gif,
-            // ImageFormat::Svg => todo!(),
+            // TODO: ImageFormat::Svg
             ImageFormat::Bmp => image::ImageFormat::Bmp,
             ImageFormat::Tiff => image::ImageFormat::Tiff,
             _ => unreachable!(),

crates/markdown/examples/markdown.rs πŸ”—

@@ -54,7 +54,7 @@ They can also be detected automatically, for example https://zed.dev/blog.
 ## Images
 Images are like links, but with an exclamation mark `!` in front.
 
-```todo!
+```markdown
 ![This is an image](/images/logo.png)
 ```
 

crates/project/src/buffer_store.rs πŸ”—

@@ -1668,7 +1668,7 @@ impl BufferStore {
                         .log_err();
                 }
 
-                // todo!(max): do something
+                // TODO(max): do something
                 // client
                 //     .send(proto::UpdateStagedText {
                 //         project_id,

crates/project/src/lsp_store.rs πŸ”—

@@ -3142,7 +3142,7 @@ impl LspStore {
     fn request_workspace_config_refresh(&mut self) {
         *self._maintain_workspace_config.1.borrow_mut() = ();
     }
-    // todo!
+
     pub fn prettier_store(&self) -> Option<Model<PrettierStore>> {
         self.as_local().map(|local| local.prettier_store.clone())
     }

crates/repl/src/notebook/notebook_ui.rs πŸ”—

@@ -515,7 +515,7 @@ impl project::ProjectItem for NotebookItem {
                     Ok(nbformat::Notebook::V4(notebook)) => notebook,
                     // 4.1 - 4.4 are converted to 4.5
                     Ok(nbformat::Notebook::Legacy(legacy_notebook)) => {
-                        // todo!(): Decide if we want to mutate the notebook by including Cell IDs
+                        // TODO: Decide if we want to mutate the notebook by including Cell IDs
                         // and any other conversions
                         let notebook = nbformat::upgrade_legacy_notebook(legacy_notebook)?;
                         notebook

crates/repl/src/outputs/markdown.rs πŸ”—

@@ -57,7 +57,7 @@ impl OutputContent for MarkdownView {
 
     fn buffer_content(&mut self, cx: &mut WindowContext) -> Option<Model<Buffer>> {
         let buffer = cx.new_model(|cx| {
-            // todo!(): Bring in the language registry so we can set the language to markdown
+            // TODO: Bring in the language registry so we can set the language to markdown
             let mut buffer = Buffer::local(self.raw_text.clone(), cx)
                 .with_language(language::PLAIN_TEXT.clone(), cx);
             buffer.set_capability(language::Capability::ReadOnly, cx);

crates/repl/src/session.rs πŸ”—

@@ -610,7 +610,7 @@ impl Session {
 
                     // Start a new kernel
                     this.update(&mut cx, |session, cx| {
-                        // todo!(): Differentiate between restart and restart+clear-outputs
+                        // TODO: Differentiate between restart and restart+clear-outputs
                         session.clear_outputs(cx);
                         session.start_kernel(cx);
                     })

crates/zed/src/zed/quick_action_bar/repl_menu.rs πŸ”—

@@ -386,7 +386,7 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
             indicator: None,
             kernel_name: kernel_name.clone(),
             kernel_language: kernel_language.clone(),
-            // todo!(): Technically not shutdown, but indeterminate
+            // TODO: Technically not shutdown, but indeterminate
             status: KernelStatus::Shutdown,
             // current_delta: Duration::default(),
         }

docs/theme/css/chrome.css πŸ”—

@@ -327,7 +327,7 @@ pre > code {
   padding: 1rem;
 }
 
-/* FIXME: ACE editors overlap their buttons because ACE does absolute
+/* TODO: ACE editors overlap their buttons because ACE does absolute
    positioning within the code block which breaks padding. The only solution I
    can think of is to move the padding to the outer pre tag (or insert a div
    wrapper), but that would require fixing a whole bunch of CSS rules.

extensions/terraform/languages/terraform-vars/highlights.scm πŸ”—

@@ -147,7 +147,7 @@
     (#any-of? @variable "workspace")))
 
 ; Terraform specific keywords
-; FIXME: ideally only for identifiers under a `variable` block to minimize false positives
+; TODO: ideally only for identifiers under a `variable` block to minimize false positives
 ((identifier) @type
   (#any-of? @type "bool" "string" "number" "object" "tuple" "list" "map" "set" "any"))
 

extensions/terraform/languages/terraform/highlights.scm πŸ”—

@@ -147,7 +147,7 @@
     (#any-of? @variable "workspace")))
 
 ; Terraform specific keywords
-; FIXME: ideally only for identifiers under a `variable` block to minimize false positives
+; TODO: ideally only for identifiers under a `variable` block to minimize false positives
 ((identifier) @type
   (#any-of? @type "bool" "string" "number" "object" "tuple" "list" "map" "set" "any"))
 

script/check-todos πŸ”—

@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# Brackets are used around characters so these don't show up in normal search.
+pattern='tod[o]!|FIXM[E]'
+result=$(git grep --no-color --ignore-case --line-number --extended-regexp -e $pattern || true)
+echo "${result}"
+if [[ -n "${result}" ]]; then
+  exit 1
+fi