Skip to content

Conversation

@nihaltp
Copy link
Contributor

@nihaltp nihaltp commented Oct 28, 2025

Closes #86

Summary by CodeRabbit

  • New Features

    • Added a timeout command to pause execution for a specified duration (0–99,999 seconds).
    • Supports interruption via Enter, with a /nobreak option to disable interruption.
    • Accepts duration as a numeric argument or /t <seconds>; -1 delegates to existing pause behavior.
  • Documentation

    • Checklist updated to mark the timeout item as completed.

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

@coderabbitai
Copy link

coderabbitai bot commented Oct 28, 2025

Warning

Rate limit exceeded

@nihaltp has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 43 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e4b7a88 and 7d5de1a.

📒 Files selected for processing (1)
  • src/main/java/com/mycmd/commands/TimeoutCommand.java (1 hunks)

Walkthrough

Introduces a new TimeoutCommand class that implements configurable timeout behavior with options for specifying seconds, delegating to PauseCommand, and enabling/disabling user input interruption via Enter key. Updates command registry in App.java and marks the timeout feature as completed in the checklist.

Changes

Cohort / File(s) Summary
Command Registration
src/main/java/com/mycmd/App.java
Adds TIMEOUT constant and registers TimeoutCommand in the command map alongside existing commands.
New Timeout Implementation
src/main/java/com/mycmd/commands/TimeoutCommand.java
New class implementing timeout functionality with argument parsing (/t <seconds>, bare numeric, /nobreak), delegation to PauseCommand for -1, optional daemon input reader for interruption, per-second countdown display, input draining, and validation (0–99999 seconds).
Project Checklist
CheckList.md
Marks "timeout" feature item as completed in the Automation & Scripting section.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Shell as ShellContext
    participant Timeout as TimeoutCommand
    participant Pause as PauseCommand
    participant Reader as InputReaderDaemon

    User->>Timeout: execute(args, context)
    Timeout->>Timeout: parse args (/t, /nobreak, bare number)

    alt timeout == -1
        Timeout->>Pause: delegate execution
        Pause->>User: pause behavior
    else timeout >= 0
        alt /nobreak not set
            Timeout->>Reader: start daemon to watch System.in
            Reader->>Timeout: signal if Enter pressed
        end

        loop each second
            Timeout->>User: print remaining seconds
        end

        alt Enter pressed
            Reader->>Timeout: interruption signal
            Timeout->>User: interrupted message
        else completed
            Timeout->>User: completion message
        end

        Timeout->>Timeout: drain remaining input
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to focus:
    • Thread lifecycle and synchronization for the input-reader daemon (TimeoutCommand).
    • Correct handling/draining of System.in to avoid blocking other commands.
    • Argument parsing edge cases and numeric range validation.
    • Delegation path to PauseCommand when /t -1 is used.

Possibly related PRs

  • [FEATURE] pause #85: Adds or changes PauseCommand and interacts with TimeoutCommand delegation logic.

Suggested reviewers

  • anshumanjadiya1102

Poem

🐰 A timeout hop, a ticking beat,

Seconds fall in steady feet,
Press Enter to stop the race,
Or send it to pause, a quieter place,
The shell now waits, then hops away with grace.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: Add timeout command to wait for a specified duration" directly and clearly describes the primary change in the pull request. It accurately summarizes that a new timeout command is being added with the capability to wait for a specified duration. The title is specific enough that teammates reviewing the history would immediately understand what was implemented, and it avoids vague language or unnecessary details. This title correctly reflects the main objective from the linked issue #86.
Linked Issues Check ✅ Passed The pull request successfully addresses all coding requirements from linked issue #86. The PR implements a new "timeout" command by introducing the TimeoutCommand class with full functionality to wait for a specified duration, including argument parsing for timeout values (in seconds), validation (0-99999 range), special handling for -1 to delegate to PauseCommand, and a live countdown mechanism. The command is properly registered in the command registry in App.java. All core functionality specified in the issue is implemented and available through the new command.
Out of Scope Changes Check ✅ Passed All changes in the pull request are directly related to implementing the timeout command feature. The modifications to App.java register the new command in the system, TimeoutCommand.java provides the complete implementation with argument parsing and timeout logic, and the CheckList.md update marks the feature as completed. No unrelated changes or technical debt items are present, and every modification is necessary and scoped to the feature objective outlined in issue #86.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/main/java/com/mycmd/commands/TimeoutCommand.java (2)

49-58: Consider extracting the magic number to a constant.

The validation logic is correct. However, the maximum timeout value (99999) is hardcoded and appears in the error message as well.

Consider extracting to a constant for maintainability:

+    private static final int MAX_TIMEOUT_SECONDS = 99999;
+
     @Override
     public void execute(String[] args, ShellContext context) {
         ...
-        if (seconds < -1 || seconds > 99999) {
+        if (seconds < -1 || seconds > MAX_TIMEOUT_SECONDS) {
             System.out.println(
-                    "Error: Invalid value for timeout specified. Valid range is 0-99999 seconds.");
+                    "Error: Invalid value for timeout specified. Valid range is 0-" + MAX_TIMEOUT_SECONDS + " seconds.");
             return;
         }

107-116: Improve the empty catch block comment.

The input cleanup logic is necessary, but the empty catch block could have a more descriptive comment explaining why it's safe to ignore the IOException.

         } catch (IOException e) {
-            // Ignore
+            // Ignore - best effort cleanup, failures don't affect functionality
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5fb4f and f1cd225.

📒 Files selected for processing (2)
  • src/main/java/com/mycmd/App.java (1 hunks)
  • src/main/java/com/mycmd/commands/TimeoutCommand.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/com/mycmd/commands/TimeoutCommand.java (1)
src/main/java/com/mycmd/ShellContext.java (1)
  • ShellContext (7-151)
🔇 Additional comments (5)
src/main/java/com/mycmd/App.java (1)

111-111: LGTM!

The timeout command registration follows the established pattern and integrates correctly with the command registry.

src/main/java/com/mycmd/commands/TimeoutCommand.java (4)

10-47: LGTM!

The argument parsing logic correctly handles all the specified formats (/t , /nobreak, bare numbers) with proper validation for duplicates and missing values. The error messages are clear and match expected command-line behavior.


60-65: LGTM!

Correctly delegates to PauseCommand when seconds is -1, matching Windows CMD timeout behavior.


83-106: LGTM!

The countdown loop correctly handles both /nobreak and normal modes, with appropriate interrupt handling and user-friendly in-place countdown updates.


118-129: LGTM!

The description and usage documentation clearly convey the command's purpose and all supported syntax variants.

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
src/main/java/com/mycmd/commands/TimeoutCommand.java (1)

76-82: Behavior now matches prompt (Enter-only). Nice.

You now exit only on Enter and the message reflects that. Good alignment with UX.

Also applies to: 103-109

🧹 Nitpick comments (3)
src/main/java/com/mycmd/commands/TimeoutCommand.java (3)

103-109: Tiny UX polish: wording.

Suggest “Enter” instead of “enter key” and consistent punctuation.

-                    "\rWaiting for "
-                            + seconds
-                            + " seconds, press "
-                            + (noBreak ? "CTRL+C to quit ..." : "enter key to continue ..."));
+                    "\rWaiting for "
+                            + seconds
+                            + " seconds; press "
+                            + (noBreak ? "CTRL+C to quit ..." : "Enter to continue ..."));

55-58: Clarify range message.

You accept -1 (delegates to pause). Consider clarifying the error to “Valid values: -1 or 0–99999 seconds.”


20-22: Direct errors to stderr.

Route error messages to System.err for better CLI ergonomics. Applies to all validation prints in this block.

- System.out.println(
+ System.err.println(

Also applies to: 30-32, 37-39, 44-45, 50-51, 55-57

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 608ce62 and 82fb7b8.

📒 Files selected for processing (2)
  • CheckList.md (1 hunks)
  • src/main/java/com/mycmd/commands/TimeoutCommand.java (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: ⚙️ Java CI Build
src/main/java/com/mycmd/commands/TimeoutCommand.java

[error] 67-67: Compilation failed: cannot find symbol 'AtomicBoolean' in TimeoutCommand.java. Ensure to import java.util.concurrent.atomic.AtomicBoolean or add the needed dependency. Command: mvn -B -DskipTests=false package

🔇 Additional comments (1)
CheckList.md (1)

120-120: Checklist update verified—timeout feature is complete and properly implemented.

The timeout item has been correctly marked as complete. Verification confirms:

  • ✓ TimeoutCommand.java exists with all required methods (execute, description, usage)
  • ✓ App.java registers TimeoutCommand at line 142
  • ✓ Implementation supports configurable timeout duration via /t <seconds> or positional argument
  • ✓ Optional /nobreak flag disables Enter key interruption; default allows interruption
  • ✓ Supports -1 for infinite wait, delegating to PauseCommand

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/main/java/com/mycmd/commands/TimeoutCommand.java (2)

16-48: Reject unknown arguments; currently ignored.

Unrecognized tokens pass through silently, producing surprising behavior. Fail fast with a clear error.

Apply this diff after the existing else if (args[i].equalsIgnoreCase("/t")) branch:

             } else if (args[i].equalsIgnoreCase("/t")) {
                 System.out.println("Error: Invalid syntax. Value expected for '/t'.");
                 return;
+            } else {
+                System.out.println("Error: Invalid syntax. Unrecognized option: " + args[i]);
+                return;
             }

71-91: Stop and join the input thread; otherwise it can steal stdin after timeout completes.

System.in.read() is blocking and not reliably interruptible. If the countdown ends without Enter, the daemon input thread keeps reading and races the shell’s Scanner. Join it deterministically and accept CR/LF as Enter. Also drain stdin on the early-exit path.

Suggested patches:

@@
-        AtomicBoolean interrupted = new AtomicBoolean(false);
-        Thread inputThread = null;
+        AtomicBoolean interrupted = new AtomicBoolean(false);
+        AtomicBoolean stopInput = new AtomicBoolean(false);
+        Thread inputThread = null;
@@
-        if (!noBreak) {
-            inputThread =
-                    new Thread(
-                            () -> {
-                                try {
-                                    int r;
-                                    // Read until a newline is encountered so we only exit on Enter
-                                    while ((r = System.in.read()) != -1) {
-                                        if (r == '\n') {
-                                            interrupted.set(true);
-                                            break;
-                                        }
-                                    }
-                                } catch (IOException e) {
-                                    // Ignore: if System.in is closed or an I/O error occurs we
-                                    // cannot reliably wait for Enter; treat as no-interrupt.
-                                }
-                            });
-            inputThread.setDaemon(true);
-            inputThread.start();
-        }
+        if (!noBreak) {
+            inputThread = new Thread(() -> {
+                try {
+                    while (!stopInput.get()) {
+                        if (System.in.available() > 0) {
+                            int r = System.in.read();
+                            // Treat CR or LF as Enter across platforms
+                            if (r == '\n' || r == '\r') {
+                                interrupted.set(true);
+                                break;
+                            }
+                        } else {
+                            try {
+                                Thread.sleep(25);
+                            } catch (InterruptedException ie) {
+                                Thread.currentThread().interrupt();
+                                break;
+                            }
+                        }
+                    }
+                } catch (IOException e) {
+                    // Best-effort; fall through.
+                }
+            });
+            inputThread.setDaemon(true);
+            inputThread.start();
+        }
@@
-            if (!noBreak && interrupted.get()) {
+            if (!noBreak && interrupted.get()) {
                 System.out.println("\r");
                 System.out.println();
-                if (inputThread != null && inputThread.isAlive()) {
-                    inputThread.interrupt();
-                }
+                if (inputThread != null) {
+                    stopInput.set(true);
+                    try {
+                        inputThread.join(200);
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt();
+                    }
+                }
+                // Drain any remaining bytes so the shell doesn't see leftovers
+                try {
+                    while (System.in.available() > 0) {
+                        System.in.read();
+                    }
+                } catch (IOException e) {
+                    // Ignore; non-fatal.
+                }
                 return;
             }
@@
-        try {
+        // Normal completion: stop the input thread before draining.
+        if (!noBreak && inputThread != null) {
+            stopInput.set(true);
+            try {
+                inputThread.join(200);
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        try {
             while (System.in.available() > 0) {
                 System.in.read();
             }
         } catch (IOException e) {
             // Ignore: if we can't drain the stream it's non-fatal; any leftover input
             // will be handled by the next read and is acceptable.
         }

Also applies to: 94-101, 122-132

🧹 Nitpick comments (1)
src/main/java/com/mycmd/commands/TimeoutCommand.java (1)

104-110: Optional: fully clear the line when the countdown shrinks.

When going 10 -> 9 seconds, a trailing character can remain because only CR is used. Consider clearing the line before printing the next message (e.g., print “\r” + ANSI clear-line “\u001B[2K”, then the message). If ANSI isn’t desired, pad with spaces.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 82fb7b8 and e4b7a88.

📒 Files selected for processing (1)
  • src/main/java/com/mycmd/commands/TimeoutCommand.java (1 hunks)
🔇 Additional comments (2)
src/main/java/com/mycmd/commands/TimeoutCommand.java (2)

1-7: Good: import fixes are in place.

Adding AtomicBoolean import resolves the prior CI failure. Nothing else needed here.


112-119: Interrupt semantics in /nobreak mode — confirm intent.

Catching InterruptedException and continue in /nobreak swallows the interrupt status, potentially masking shutdown signals. Is this intentional? If not, consider preserving the flag or exiting the loop.

@github-actions
Copy link

🚀 Hi @nihaltp!

Thank you for contributing to MyCMD. A maintainer will review your PR shortly. 🎉

@anshumanjadiya1102 anshumanjadiya1102 merged commit add7dbb into Drive-for-Java:main Oct 29, 2025
4 checks passed
@anshumanjadiya1102 anshumanjadiya1102 added hacktoberfest-accepted This is for Hacktoberfest hacktoberfest This is for Hacktoberfest and removed needs-review labels Oct 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

from-fork hacktoberfest This is for Hacktoberfest hacktoberfest-accepted This is for Hacktoberfest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] timeout

2 participants