Skip to content

Commit bfe753c

Browse files
authored
Support named config file (#766)
2 parents d0ee6a7 + 4fd1163 commit bfe753c

File tree

2 files changed

+53
-34
lines changed

2 files changed

+53
-34
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ optional arguments:
138138
-l, --language {bigquery,db2,db2i,hive,mariadb,mysql,n1ql,plsql,postgresql,redshift,singlestoredb,snowflake,spark,sql,sqlite,tidb,trino,tsql}
139139
SQL dialect (defaults to basic sql)
140140
-c, --config CONFIG
141-
Path to config JSON file or json string (will use default configs if unspecified)
141+
Path to config JSON file or json string (will find a file named '.sql-formatter.json' or use default configs if unspecified)
142142
--version show program's version number and exit
143143
```
144144

@@ -158,7 +158,7 @@ where
158158
id = 3
159159
```
160160

161-
The tool also accepts a JSON config file with the `--config` option that takes this form:
161+
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:
162162

163163
```json
164164
{

bin/sql-formatter-cli.cjs

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
const { format, supportedDialects } = require('../dist/index.cjs');
66
const fs = require('fs');
7+
const path = require('path');
78
const tty = require('tty');
89
const { version } = require('../package.json');
910
const { ArgumentParser } = require('argparse');
@@ -52,7 +53,7 @@ class SqlFormatterCli {
5253
});
5354

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

5859
parser.add_argument('--version', {
@@ -72,57 +73,75 @@ class SqlFormatterCli {
7273
process.exit(0);
7374
}
7475

76+
return {
77+
language: this.args.language,
78+
...(await this.getConfig()),
79+
};
80+
}
81+
82+
async getConfig() {
7583
if (this.args.config) {
7684
// First, try to parse --config value as a JSON string
7785
try {
78-
const configJson = JSON.parse(this.args.config);
79-
return { language: this.args.language, ...configJson };
86+
return JSON.parse(this.args.config);
8087
} catch (e) {
8188
// If that fails, try to read the --config value as a file
82-
try {
83-
const configFile = await this.readFile(this.args.config);
84-
const configJson = JSON.parse(configFile);
85-
return { language: this.args.language, ...configJson };
86-
} catch (e) {
87-
if (e instanceof SyntaxError) {
88-
console.error(
89-
`Error: unable to parse as JSON or treat as JSON file: ${this.args.config}`
90-
);
91-
process.exit(1);
92-
}
93-
this.exitWhenIOError(e);
94-
console.error('An unknown error has occurred, please file a bug report at:');
95-
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
96-
throw e;
97-
}
89+
return this.parseFile(this.args.config);
9890
}
9991
}
100-
return {
101-
language: this.args.language,
102-
};
92+
93+
// Otherwise find a local config file
94+
const localConfig = await this.findConfig();
95+
if (!localConfig) {
96+
return null;
97+
}
98+
99+
return this.parseFile(localConfig);
100+
}
101+
102+
findConfig(dir = __dirname) {
103+
const filePath = path.join(dir, '.sql-formatter.json');
104+
if (!fs.existsSync(filePath)) {
105+
const parentDir = path.resolve(dir, '..');
106+
if (parentDir === dir) {
107+
return null;
108+
}
109+
return this.findConfig(parentDir);
110+
}
111+
112+
return filePath;
103113
}
104114

105115
async getInput() {
106116
const infile = this.args.file || process.stdin.fd;
107117
if (this.args.file) {
108-
try {
109-
return await this.readFile(infile, { encoding: 'utf-8' });
110-
} catch (e) {
111-
this.exitWhenIOError(e);
112-
console.error('An unknown error has occurred, please file a bug report at:');
113-
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
114-
throw e;
115-
}
118+
return await this.readFile(infile);
116119
} else {
117120
return await getStdin();
118121
}
119122
}
120123

124+
async parseFile(filename) {
125+
try {
126+
return JSON.parse(await this.readFile(filename));
127+
} catch (e) {
128+
console.error(`Error: unable to parse as JSON or treat as JSON file: ${filename}`);
129+
process.exit(1);
130+
}
131+
}
132+
121133
async readFile(filename) {
122-
return promisify(fs.readFile)(filename, { encoding: 'utf-8' });
134+
try {
135+
return promisify(fs.readFile)(filename, { encoding: 'utf-8' });
136+
} catch (e) {
137+
this.exitWhenIOError(e, filename);
138+
console.error('An unknown error has occurred, please file a bug report at:');
139+
console.log('https://github.com/sql-formatter-org/sql-formatter/issues\n');
140+
throw e;
141+
}
123142
}
124143

125-
exitWhenIOError(e) {
144+
exitWhenIOError(e, infile) {
126145
if (e.code === 'EAGAIN') {
127146
console.error('Error: no file specified and no data in stdin');
128147
process.exit(1);

0 commit comments

Comments
 (0)