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

Commiting from project subfolder does not work #1196

Open
3 tasks done
izi-p opened this issue Sep 12, 2023 · 4 comments
Open
3 tasks done

Commiting from project subfolder does not work #1196

izi-p opened this issue Sep 12, 2023 · 4 comments

Comments

@izi-p
Copy link

izi-p commented Sep 12, 2023

Discussion

Hello,

I want to use gitmoji-cli in my project. I set up the gitmoji config in package.json file.
When I commit from project root, where package.json file is located, everything works as expected.

However, when commiting from a subfolder of the project (for example, src folder), it does not find config and use the default config.

Am I doing something wrong or is this feature not available?

Thank you

Validations

@izi-p izi-p changed the title Global project gitmoji config Commiting from project subfolder does not work Sep 12, 2023
@carloscuesta
Copy link
Owner

Hey!

Thanks for opening an issue, indeed it looks like a bug since we use the cwd to get the package.json therefore if you try to commit within a subdirectory it will not pick up the configuration and the fallback will be served instead.

See:

const packageJson = `${cwd()}/package.json`

🤔 Thinking out loud, I'm not sure how other tools approach this but it's a fair use-case to think people can commit from subdirectories.

The problem is that if we want to implement this it can be tricky to start traversing each directory (up) until you find a file that contains a configuration file 😅

I think we should somehow get the absolute directory for the git repo and try to find the configuration files there instead of relying on the current working directory.

@izi-p
Copy link
Author

izi-p commented Sep 28, 2023

Hey Carloscuesta

It looks like NPM does like this

Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a package.json file, or a node_modules folder. If such a thing is found, then that is treated as the effective "current directory" for the purpose of running npm commands. (This behavior is inspired by and similar to git's .git-folder seeking logic when running git commands in a working dir.)

https://docs.npmjs.com/cli/v7/configuring-npm/folders

Maybe we can implement the same way as they do. We can also limit to a certain amount of folders to make sure the calculation does not take forever.

It's also important to note that for a monorepo, we usually commit in project subfolders (packages folders), but we might want a global gitmoji config for the whole project.

.gitmojirc.json
package.json
packages/
----my-package/
--------package.json
--------src/
----my-second-package/
--------package.json
--------src/

For this use case, we would need a global .gitmojirc.json file and recursively walking up folders to find it in the project root.

Pierre

@izi-p
Copy link
Author

izi-p commented Sep 28, 2023

I ran into this PR as well, so it used to work maybe

#57

@segersniels
Copy link
Collaborator

segersniels commented Nov 9, 2023

There's definitely pretty straight forward ways to achieve this. Something like this should suffice to find either package.json with a gitmoji config or a .gitmojirc.json file:

import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';

function findWorkspaceRoot() {
  try {
    const stdout = execSync('git rev-parse --show-toplevel');

    return stdout.toString().trim();
  } catch (err) {
    return;
  }
}

enum ConfigType {
  Package = 'package.json',
  Config = '.gitmojirc.json',
}

function findConfigDir(type: ConfigType) {
  const root = findWorkspaceRoot();

  let currentDir = process.cwd();
  while (true) {
    const configPath = path.join(currentDir, type);
    if (fs.existsSync(configPath)) {
      if (type === ConfigType.Package) {
        const packageJson = JSON.parse(fs.readFileSync(configPath, 'utf8'));

        if (packageJson.gitmoji) {
          return currentDir;
        }
      } else {
        return currentDir;
      }
    }

    if (currentDir === (root ?? path.dirname(currentDir))) {
      break;
    }

    currentDir = path.dirname(currentDir);
  }

  throw new Error('Reached root without finding gitmoji config');
}

findConfigDir(ConfigType.Package);

Basically crawl up the parent directories until you find a directory that has a config file that is usable. In an ideal scenario git rev-parse --show-toplevel returns the top level of the repository. But if that fails it just crawls up the filesystem until / is reached.

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

3 participants