Unibeautify/cli

Global configuration file

Opened this issue · 10 comments

The VS Code extension already got the option to pass a default config file, if no config file is provided in the project itself. We could do the same in two ways:

  1. we have the Unibeautify config file in the user root ~/.unibeautifyrc.json
  2. we use the ~/.unibeautifrc.json file to set CLI options e.g.:
{
  "defaultConfig": "/Users/marvinheilemann/Documents/Configs/.unibeautifyrc.json"
}

I like this. Personal default settings for quick scripts.

We could follow the conventions of Unix desktop environments (GNOME, KDE) and put the files in the ~/.config directory. People have so many dotfiles in the home directory already :) The ~/.config directory is already used by lots of programs, even command line programs.

So the full filename could be ~/.config/unibeautifyrc.json - or ~/.config/unibeautify/rc.json if we want Unibeautify to have its own subdirectory.

(To be pedantic, the location of the config directory comes from the environment variable $XDG_CONFIG_HOME but I think practically everyone just uses the default location, ~/.config).

(There's a similar convention of using the ~/.cache directory if we ever need to cache something.)

I am not in support of the Unibeautify configuration file having an option pointing to an absolute path, such as in @muuvmuuv 's example #2: #104 (comment)

Here's the discussion we had over in VSCode project: Unibeautify/vscode#55 (comment)
I was OK with adding defaultConfig to VSCode's configuration because I see a valid workflow: having VSCode User Settings with unibeautify.defaultConfig pointing to say ~/.unibeautifyrc.

I'd recommend using unibeautify --config-file /Users/marvinheilemann/Documents/Configs/.unibeautifyrc.json.

I think Cosmiconfig -- which Unibeautify uses -- already searches the home directory: https://github.com/davidtheclark/cosmiconfig#explorersearch
Using search: https://github.com/Unibeautify/unibeautify-cli/blob/74ee41fb76c154b107f29b22457100a05ece993f/src/commands/BeautifyCommand.ts#L77

I am not in support of the Unibeautify configuration file having an option pointing to an absolute path

Agreed. I think it would be a good idea to support user defaults, but the pathname should be implicit (always in a standard location) or given to the CLI as --config-file, not specified in other .unibeutifyrc files.

@lassik yep, that is what I meant by 1. So the user places a config file in eg ~/.config/.unibeautifyrc.json and Unibeautify will use this if 1. no config is defined via flag and 2. cosmiconfig search couldn‘t find a config (or maybe 3. no .editorconfig is in place)

Sent with GitHawk

So the user places a config file in eg ~/.config/.unibeautifyrc.json

The standard path would be ~/.unibeautifyrc.json, not ~/.config/....

See https://github.com/davidtheclark/cosmiconfig#explorersearch and https://github.com/davidtheclark/cosmiconfig#stopdir

However, this may only work if your code is within your home directory.

Looks like it would not currently work because of the stopDir in https://github.com/Unibeautify/unibeautify-cli/blob/74ee41fb76c154b107f29b22457100a05ece993f/src/commands/BeautifyCommand.ts#L74-L77

cosmiconfig("unibeautify", { stopDir: filePath });

@muuvmuuv As mentioned in #104 (comment) my recommendation is to use the already supported --config-file CLI argument:

unibeautify --config-file /Users/marvinheilemann/Documents/Configs/.unibeautifyrc.json

My problem with allowing these global configuration files is they should really be stored within the project itself so they can be shared throughout your team. It means if I clone your repository, I am not able to reproduce the same results and therefore creates a confusing experience.

At this time, I'm not confident I would even accept a Pull Request implementing this global configuration support by changing stopDir 🤔 .

@Glavin001 I didn't mean to replace a projects config file, I totally agree to share configs within a project. I mean just for fast beautifications somewhere outside my projects. I often place files in ~/Downloads just for quick editing when I work with a CMS and do not want to use the CMS build-in editor. With this global config, I just have to unibeautify file.txt and it just works. This would fasten my process.

  1. no config is defined via flag and 2. cosmiconfig search couldn‘t find a config (or maybe 3. no .editorconfig is in place)

This would be the query, so only if 1. and 2. did not find anything, we would try to load ~/.unibeautifyrc.

My problem with allowing these global configuration files is they should really be stored within the project itself so they can be shared throughout your team. It means if I clone your repository, I am not able to reproduce the same results and therefore creates a confusing experience.

I fully agree, but the point of the global file would be to serve defaults for one-off hacks (e.g. when you spend an hour writing a throwaway script - code formatting is still very useful in these situations). It could also serve as the default for temporary code in a text editor that isn't saved to any file (I often do this several times a day to work out some ideas). Similar to the way text editors have default settings for coding style but can change them per project.

So the user places a config file in eg

The standard path would be ~/.unibeautifyrc.json, not ~/.config/....

It seems all of us are actually confusing two different approaches here.

  • One is to look up in parent directories until reaching the home directory (what CosmicConfig seems to do).

  • The other approach is to look right away in a known default location (~/.unibeautifyrc.json or ~/.config/.unibeautifyrc.json) no matter where the file to beautify is (even if it's outside the user's home directory).

It's true that traditionally config files have gone directly under the homedir, but ~/.config has also been a de facto standard for years. Almost everyone has that directory already because lots of programs put their stuff in there.

Another way to put it: to inherit/extend a coding style should be a separate matter from the default coding style. The default style should only be used for files/projects that don't have any config file of their own.

I often place files in ~/Downloads just for quick editing
and
the point of the global file would be to serve defaults for one-off hacks (e.g. when you spend an hour writing a throwaway script - code formatting is still very useful in these situations). It could also serve as the default for temporary code in a text editor that isn't saved to any file (I often do this several times a day to work out some ideas).

Agreed. I follow these practices, too, and would benefit.

With this global config, I just have to unibeautify file.txt and it just works. This would fasten my process.

So currently we can already use unibeautify --config-file ~/.unibeautifyrc.yml file.txt and we want to remove the requirement for --config-file.

Similar to the way text editors have default settings for coding style but can change them per project.

This is possible now for VSCode with the merge of Unibeautify/vscode#57 and we just want this also to be available for Unibeautify CLI 🤔 .


I am OK with a Unibeautify CLI solution which is not available in the Unibeautify core.
I want it to be deterministic based off of the project directory alone how to beautify an entire project's source code files.

I see unibeautify <file> as a very specific and helpful use case.

Instead of changing or removing stopDir, I would be open to a PR changing how the "missing config file" case is handled:

https://github.com/Unibeautify/unibeautify-cli/blob/5e04f0c86c8e5662ce08e3d04a6bdd9d05d2cee2/src/commands/BeautifyCommand.ts#L81

Something like:

private configFile({
    configFile,
    filePath,
  }: {
    configFile?: string;
    filePath?: string;
  }) {
    const configExplorer = cosmiconfig("unibeautify", { stopDir: filePath });
    const loadConfigPromise = configFile
      ? configExplorer.load(configFile)
      : configExplorer.search(filePath);
    return loadConfigPromise
      .then(result => (result ? result.config : null))
      .catch(error => {
            // ======== CHANGE BELOW HERE
            const homeDir = require('os').homedir();
            const defaultConfigExplorer = cosmiconfig("unibeautify", { stopDir: homeDir });
            return configExplorer.load(homeDir);
      })
      .catch(error =>
        Promise.reject(
          new Error(`Could not load configuration file ${configFile}`)
        )
      );
  }

Good thinking. In light of this, I would suggest one of the following:

  • Look for the default config file if there is no project config file only when --default is given.
  • Look for the default config file if there is no project config file unless --nodefault is given.

The right spelling (default vs defaults, nodefault vs no-default) is not clear.