Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prune orphaned todos command #577

Open
tylerbecks opened this issue Apr 11, 2023 · 1 comment
Open

Add prune orphaned todos command #577

tylerbecks opened this issue Apr 11, 2023 · 1 comment

Comments

@tylerbecks
Copy link

Currently, there is no command to remove orphaned todos. There are 2 ways that todos can become orphaned (that I can think of):

  1. the file for the todo no longer exists (it was moved or deleted)
  2. the rule the todo was created for was removed/disabled

After realizing the performance impact of the lint-todo system with many todos, we are prioritizing reducing the line count in the .lint-todo file as much as possible.

Here is an example of a command I wrote to clean up todo for files that no longer exist (case 1)

const fs = require('fs');

/**
 * This script parses a .lint-todo file and removes lines for non-existent files in the current working directory.
 *
 * Usage:
 *     node scripts/lint-todo-dead-file-cleaner.js /path/to/your/.lint-todo
 *
 * Replace '/path/to/your/.lint-todo' with the actual path to your .lint-todo file.
 *
 */

/**
 * Parses the contents of a .lint-todo file and returns a set of unique file paths and a list of lines from the file.
 * @param {string} filePath - The path to the .lint-todo file.
 * @returns {[Set<string>, string[]]} - A tuple containing a set of unique file paths and a list of lines from the file.
 */
function parseLintTodoFile(filePath) {
  const lines = fs.readFileSync(filePath, { encoding: 'utf8' }).split('\n');
  const filePaths = lines.map((line) => line.split('|').pop().trim()).filter(Boolean);
  return {
    filePaths: new Set(filePaths),
    lines
  };
}

/**
 * Checks if a file exists.
 * @param {string} filePath - The path to the file.
 * @returns {boolean} - `true` if the file exists, `false` otherwise.
 */
function checkFileExists(filePath) {
  return fs.existsSync(filePath);
}

/**
 * Removes lines for non-existent files from a .lint-todo file.
 * @param {string} filePath - The path to the .lint-todo file.
 * @param {string[]} lines - A list of lines from the .lint-todo file.
 * @param {Set<string>} nonexistentFiles - A set of non-existent file paths.
 */
function removeNonexistentFiles(filePath, lines, nonexistentFiles) {
  fs.writeFileSync(
    filePath,
    lines
      .filter((line) => {
        const filePath = line.split('|').pop().trim();
        return !nonexistentFiles.has(filePath);
      })
      .join('\n')
  );
}

/**
 * Entry point for the script. Parses command line arguments, checks for non-existent files, and removes their lines from the .lint-todo file.
 */
function main() {
  const filePath = process.argv[2];

  const { filePaths, lines } = parseLintTodoFile(filePath);
  const nonexistentFiles = new Set(Array.from(filePaths).filter((filePath) => !checkFileExists(filePath)));

  if (nonexistentFiles.size > 0) {
    removeNonexistentFiles(filePath, lines, nonexistentFiles);
    console.log(`${nonexistentFiles.size} dead files detected in .lint-todo:`);
    for (const filePath of nonexistentFiles) {
      console.log(`  - ${filePath}`);
    }

    const { lines: newLines } = parseLintTodoFile(filePath);
    console.log(`Removed ${lines.length - newLines.length} lines from the .lint-todo file`);
  } else {
    console.log('All files listed in the .lint-todo file exist.');
  }
}

main();
@Techn1x
Copy link
Contributor

Techn1x commented Aug 11, 2023

Noticed this the other day as well - would love for this to run as part of compacting the todo list

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants