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

Read config from pyproject.toml #1039

Merged
merged 13 commits into from
May 28, 2021
Merged

Read config from pyproject.toml #1039

merged 13 commits into from
May 28, 2021

Conversation

edgarrmondragon
Copy link
Contributor

@edgarrmondragon edgarrmondragon commented May 11, 2021

This PR adds support for pyproject.toml as a configuration source.

It would help keeping all configuration for a Python project in a single file, since this file is used by other major Python projects like black and pytest.

Some implementation details:

  • Takes precedence over .sqlfluff.

  • core section lives in [tool.sqlfluff.core].

    [tool.sqlfluff.core]
    templater = "jinja"
    sql_file_exts = [
        ".sql",
        ".sql.j2",
        ".dml",
        ".ddl",
    ]
    
    [tool.sqlfluff.indentation]
    indented_joins = false
    template_blocks_indent = false
    
    [tool.sqlfluff.templater]
    unwrap_wrapped_queries = true
    
    [tool.sqlfluff.templater.jinja]
    apply_dbt_builtins = true

Closes #890

@codecov
Copy link

codecov bot commented May 11, 2021

Codecov Report

Merging #1039 (d034311) into master (454c290) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1039   +/-   ##
=======================================
  Coverage   95.99%   96.00%           
=======================================
  Files         123      123           
  Lines        8157     8176   +19     
=======================================
+ Hits         7830     7849   +19     
  Misses        327      327           
Flag Coverage Δ
dbt017-py38 61.47% <45.45%> (-0.06%) ⬇️
dbt018-py38 61.49% <45.45%> (-0.06%) ⬇️
dbt019-py38 61.49% <45.45%> (-0.06%) ⬇️
py36 94.90% <100.00%> (+0.01%) ⬆️
py37 94.94% <100.00%> (+0.01%) ⬆️
py38 94.92% <100.00%> (+0.01%) ⬆️
py39 94.92% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/sqlfluff/core/config.py 96.60% <100.00%> (+0.26%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 454c290...d034311. Read the comment docs.

Copy link
Member

@barrywhart barrywhart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR looks pretty good. I would like to understand the reason for the "__options" suffix in the .toml file. I wonder if there may be other options.

Also, I think we need to update the configuration docs in ocs/source/configuration.rst, which documents how configuration works, what files it looks at, etc.

*[sqlfluff:jinjacontext]*.

For the `pyproject.toml file`_, all valid sections start with `tool.sqlfluff`
and subsections are delimited by a dot and suffixed with *__options*.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned the __options suffix in the PR description. Can you give an example of the kind of conflict you're avoiding by doing this?

If I understand correctly, could the toml reader skip sections that don't start with tools.sqlfluff or sqlfluff?

Copy link
Contributor Author

@edgarrmondragon edgarrmondragon May 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a TOML is basically a nested object/dictionary and the keys would collide. The following code raises an error

import toml

content = """
[tool.sqlfluff]
templater = "jinja"

[tool.sqlfluff.templater]
unwrap_wrapped_queries = true
"""

toml.loads(content)

The error is:

What? templater already exists?{'templater': 'jinja'} (line 5 column 1 char 38)

If I understand correctly, could the toml reader skip sections that don't start with tools.sqlfluff or sqlfluff?

Yes, the other sections are ignored. The convention I believe is to put every set of configurations for my_tool under [tool.my_tool*] sections.

src/sqlfluff/core/config.py Outdated Show resolved Hide resolved
the first is a tuple of paths, the second is the value at that path.
"""
config = toml.load(fpath)
tool = config.get("tool", {}).get("sqlfluff", {})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you replaced __options with the tool.sqlfluff.core technique, do you need to move or place the core values to match the structure of the other config file types?

In other words, have you verified that SQLFluff correctly uses the values from the core section?

[tool.sqlfluff.core]
    templater = "jinja"
    sql_file_exts = [
        ".sql",
        ".sql.j2",
        ".dml",
        ".ddl",
    ]

Copy link
Contributor Author

@edgarrmondragon edgarrmondragon May 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barrywhart I added a test case with

[tool.sqlfluff.core]
testing_int = 5
testing_bar = 7.698
testing_bool = false
testing_arr = [ "a", "b", "c" ]
testing_inline_table = { x = 1 }
 
[tool.sqlfluff.bar]
foo = "foobar"

[tool.sqlfluff.fnarr.fnarr]
foo = "foobar"

which gets collected into the following dict:

{
    "core": {
        "testing_int": 5,
        "testing_bar": 7.698,
        "testing_bool": False,
        "testing_arr": ["a", "b", "c"],
        "testing_inline_table": {"x": 1},
    },
    "bar": {"foo": "foobar"},
    "fnarr": {"fnarr": {"foo": "foobar"}},
}

does it look right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I'd feel much better if you could do some manual tests to confirm the settings in the TOML file are being read correctly and actually affecting the runtime behavior of SQLFluff. There are sometimes limits to the effectiveness of automated tests and manual review, and I think this is one of those times.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barrywhart That makes a lot of sense. I created this repo to test some configurations. Let me know if you think there are edge cases I could add.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested with your example repo. Works great! I also added a simple test with templating. This is based on the Variable Templating example from the SQLFluff docs.

test.sql:

SELECT {{ num_things }} FROM {{ tbl_name }} WHERE id > 10 LIMIT 5

Additions to pyproject.toml:

[tool.sqlfluff.core]
templater = "jinja"

[tool.sqlfluff.templater.jinja.context]
num_things=456
tbl_name="my_table"

Copy link
Contributor Author

@edgarrmondragon edgarrmondragon May 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added that templated case to the example repo 😄.

Copy link
Member

@barrywhart barrywhart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for adding the test project. 👍

@NiallRees NiallRees merged commit 850758d into sqlfluff:master May 28, 2021
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

Successfully merging this pull request may close these issues.

Look for project configuration in pyproject.toml.
3 participants