Skip to content

Commit

Permalink
Support named config file (#766)
Browse files Browse the repository at this point in the history
  • Loading branch information
nene authored Aug 9, 2024
2 parents d0ee6a7 + 4fd1163 commit bfe753c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ optional arguments:
-l, --language {bigquery,db2,db2i,hive,mariadb,mysql,n1ql,plsql,postgresql,redshift,singlestoredb,snowflake,spark,sql,sqlite,tidb,trino,tsql}
SQL dialect (defaults to basic sql)
-c, --config CONFIG
Path to config JSON file or json string (will use default configs if unspecified)
Path to config JSON file or json string (will find a file named '.sql-formatter.json' or use default configs if unspecified)
--version show program's version number and exit
```

Expand All @@ -158,7 +158,7 @@ where
id = 3
```

The tool also accepts a JSON config file with the `--config` option that takes this form:
The tool also accepts a JSON config file named .sql-formatter.json in the current or any parent directory, or with the `--config` option that takes this form:

```json
{
Expand Down
83 changes: 51 additions & 32 deletions bin/sql-formatter-cli.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const { format, supportedDialects } = require('../dist/index.cjs');
const fs = require('fs');
const path = require('path');
const tty = require('tty');
const { version } = require('../package.json');
const { ArgumentParser } = require('argparse');
Expand Down Expand Up @@ -52,7 +53,7 @@ class SqlFormatterCli {
});

parser.add_argument('-c', '--config', {
help: 'Path to config JSON file or json string (will use default configs if unspecified)',
help: 'Path to config JSON file or json string (will find a file named \'.sql-formatter.json\' or use default configs if unspecified)',
});

parser.add_argument('--version', {
Expand All @@ -72,57 +73,75 @@ class SqlFormatterCli {
process.exit(0);
}

return {
language: this.args.language,
...(await this.getConfig()),
};
}

async getConfig() {
if (this.args.config) {
// First, try to parse --config value as a JSON string
try {
const configJson = JSON.parse(this.args.config);
return { language: this.args.language, ...configJson };
return JSON.parse(this.args.config);
} catch (e) {
// If that fails, try to read the --config value as a file
try {
const configFile = await this.readFile(this.args.config);
const configJson = JSON.parse(configFile);
return { language: this.args.language, ...configJson };
} catch (e) {
if (e instanceof SyntaxError) {
console.error(
`Error: unable to parse as JSON or treat as JSON file: ${this.args.config}`
);
process.exit(1);
}
this.exitWhenIOError(e);
console.error('An unknown error has occurred, please file a bug report at:');
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
throw e;
}
return this.parseFile(this.args.config);
}
}
return {
language: this.args.language,
};

// Otherwise find a local config file
const localConfig = await this.findConfig();
if (!localConfig) {
return null;
}

return this.parseFile(localConfig);
}

findConfig(dir = __dirname) {
const filePath = path.join(dir, '.sql-formatter.json');
if (!fs.existsSync(filePath)) {
const parentDir = path.resolve(dir, '..');
if (parentDir === dir) {
return null;
}
return this.findConfig(parentDir);
}

return filePath;
}

async getInput() {
const infile = this.args.file || process.stdin.fd;
if (this.args.file) {
try {
return await this.readFile(infile, { encoding: 'utf-8' });
} catch (e) {
this.exitWhenIOError(e);
console.error('An unknown error has occurred, please file a bug report at:');
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
throw e;
}
return await this.readFile(infile);
} else {
return await getStdin();
}
}

async parseFile(filename) {
try {
return JSON.parse(await this.readFile(filename));
} catch (e) {
console.error(`Error: unable to parse as JSON or treat as JSON file: ${filename}`);
process.exit(1);
}
}

async readFile(filename) {
return promisify(fs.readFile)(filename, { encoding: 'utf-8' });
try {
return promisify(fs.readFile)(filename, { encoding: 'utf-8' });
} catch (e) {
this.exitWhenIOError(e, filename);
console.error('An unknown error has occurred, please file a bug report at:');
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
throw e;
}
}

exitWhenIOError(e) {
exitWhenIOError(e, infile) {
if (e.code === 'EAGAIN') {
console.error('Error: no file specified and no data in stdin');
process.exit(1);
Expand Down

0 comments on commit bfe753c

Please sign in to comment.