How best to return the number of files in a directory (including subdirectories)?

I am trying to efficiently retrieve the number of files contained in a workspace so that I can prevent processing too many files. To do this, I thought it might make the most sense to run the “find . -type f | wc -l” shell command, which I thought I could do using a Nova process. However, for some reason I cannot get this to work. I have spent far more time on this than I care to admit :grinning:. Can an anyone point me in the right direction? Below is the code I have so far. Thanks!

return new Promise(resolve => {
      const process = new Process("/usr/bin/env", {
          // args: ["ruby", "--version"],
          args: [find "${nova.workspace.path}" -type f | wc -l],
          // cwd: nova.workspace.path,
          // shell: true
      });
      console.log(process.args);
      let output = "";
      process.onStdout(line => output += line.trim());
      process.onDidExit(status => {
          if (status === 0) {
              console.log(output: ${output});
              resolve(this._isGlobal = true);
          } else {
            console.log("something else");
            console.log(output);
              resolve(this._isGlobal = false);
          }
      });

      process.start();
  });

To use the | you would need to pass the args to a shell, such as /bin/sh. Here is another take that just counts the lines in Nova, avoiding needing to prepare things for the shell, which can be fraught with landmines:

function findThings() {
  return new Promise((resolve, reject) => {
    const process = new Process("/usr/bin/find", {
      args: [nova.workspace.path, "-type", "f"],
    });

    let count = 0;
    let output = "";
    let errOutput = "";
    process.onStdout((line) => {
      count++;
      output += line.trim();
    });
    process.onStderr((line) => {
      errOutput += line.trim();
    });
    process.onDidExit((status) => {
      if (status === 0) {
        resolve(count);
      } else {
        reject({
          status: status,
          stdout: output,
          stderr: errOutput,
        });
      }
    });
    process.start();
  });
}

function findCommand() {
  findThings()
    .then((value) => {
      console.log(`Found ${value}`);
    })
    .catch((status) => {
      console.log(`findThings failed with status ${status.status}`);
      console.log(`findThing stdout: ${status.stdout}`);
      console.log(`findThing stderr: ${status.stderr}`);
    });
}

You could also do the whole thing natively in Nova with FileSystem and FileStats and a bit of recursion.

1 Like

Thanks so much John! I will give this a try and let you know how I make out.

To update, I decided just to do it natively in Nova. I figured there wasn’t much difference in the amount of code, so why require another extension entitlement.

Thanks again @jrf! I appreciate you taking the time to respond.