Skip to content

Commit a6895d3

Browse files
authored
Enable using custom documentation index.html file per dbt project (#15)
* Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file * Override documentation html file
1 parent 150d2f6 commit a6895d3

File tree

6 files changed

+263
-19
lines changed

6 files changed

+263
-19
lines changed

opendbt/client.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import dbt
2-
from dbt.adapters.base.plugin import AdapterPlugin
31
from dbt.cli.main import dbtRunner as DbtCliRunner
42
from dbt.cli.main import dbtRunnerResult
53
from dbt.contracts.results import RunResult
@@ -11,21 +9,25 @@
119
# ================================================================================================================
1210
# Monkey Patching! Override dbt lib AdapterContainer.register_adapter method with new one above
1311
# ================================================================================================================
14-
from opendbt import dbtcommon
12+
from opendbt import dbtcommon as opendbt_dbtcommon
13+
from dbt.adapters.factory import AdapterContainer
1514

16-
# STEP-1 add new methods
17-
dbt.adapters.factory.AdapterContainer.get_custom_adapter_config_value = dbtcommon.get_custom_adapter_config_value
18-
dbt.adapters.factory.AdapterContainer.get_custom_adapter_class_by_name = dbtcommon.get_custom_adapter_class_by_name
19-
# # STEP-2 override existing method
2015
if Version(DBT_VERSION.to_version_string(skip_matcher=True)) > Version("1.8.0"):
21-
from opendbt import dbt18
22-
23-
dbt.adapters.factory.AdapterContainer.register_adapter = dbt18.register_adapter
16+
from opendbt import dbt18 as opendbt
17+
from dbt.task.docs.generate import GenerateTask
2418
else:
25-
from opendbt import dbt17
26-
27-
dbt.adapters.factory.AdapterContainer.register_adapter = dbt17.register_adapter
28-
19+
from opendbt import dbt17 as opendbt
20+
from dbt.task.generate import GenerateTask
21+
22+
# ================= add new methods =======================================================
23+
AdapterContainer.get_custom_adapter_config_value = opendbt_dbtcommon.get_custom_adapter_config_value
24+
AdapterContainer.get_custom_adapter_class_by_name = opendbt_dbtcommon.get_custom_adapter_class_by_name
25+
# ================= override existing methods ==============================================
26+
# dbt docs overrides
27+
GenerateTask.dbt_run = GenerateTask.run
28+
GenerateTask.run = opendbt_dbtcommon.GenerateTask_run
29+
# Adapter inheritance override
30+
AdapterContainer.register_adapter = opendbt.register_adapter
2931

3032
class OpenDbtCli:
3133

@@ -54,4 +56,7 @@ def run(args: list) -> dbtRunnerResult:
5456

5557
if _exception is None:
5658
DbtRuntimeError(f"DBT execution failed!")
57-
raise _exception
59+
if _exception:
60+
raise _exception
61+
else:
62+
return result

opendbt/dbtcommon.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import importlib
22

33
DBT_CUSTOM_ADAPTER_VAR = 'dbt_custom_adapter'
4+
import shutil
5+
from pathlib import Path
6+
import click
47

58

69
def get_custom_adapter_config_value(self, config: 'AdapterRequiredConfig') -> str:
@@ -30,3 +33,16 @@ def get_custom_adapter_class_by_name(self, custom_adapter_class_name: str):
3033
return user_adapter_class
3134
except ModuleNotFoundError as mnfe:
3235
raise Exception(f"Module of provided adapter not found, provided: {custom_adapter_class_name}") from mnfe
36+
37+
38+
def GenerateTask_run(self):
39+
# Call the original dbt run method
40+
self.dbt_run()
41+
target = Path(self.config.project_target_path).joinpath("index.html")
42+
for dir in self.config.docs_paths:
43+
index_html = Path(self.config.project_root).joinpath(dir).joinpath("index.html")
44+
if index_html.is_file() and index_html.exists():
45+
# override default dbt provided index.html with user index.html file
46+
shutil.copyfile(index_html, target)
47+
click.echo(f"Using user provided documentation page: {index_html.as_posix()}")
48+
break

opendbt/docs/index.html

Lines changed: 206 additions & 0 deletions
Large diffs are not rendered by default.

tests/resources/dbttest/dbt_project.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ seed-paths: [ "seeds" ]
1717
# include "opendbt/macros/" macros!
1818
macro-paths: [ "macros", "../../../opendbt/macros/" ]
1919
snapshot-paths: [ "snapshots" ]
20+
# include "opendbt/docs/" project folder!
21+
docs-paths: [ "../../../opendbt/docs/" ]
2022

2123
clean-targets: # directories to be removed by `dbt clean`
2224
- "target"

tests/test_dbt_docs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import unittest
2+
from pathlib import Path
3+
from unittest import TestCase
4+
5+
from opendbt import OpenDbtProject
6+
7+
8+
class TestDbtDocs(TestCase):
9+
RESOURCES_DIR = Path(__file__).parent.joinpath("resources")
10+
DBTTEST_DIR = RESOURCES_DIR.joinpath("dbttest")
11+
12+
def test_run_docs_generate(self):
13+
dp = OpenDbtProject(project_dir=self.DBTTEST_DIR, profiles_dir=self.DBTTEST_DIR)
14+
dp.run(command="docs", args=['generate'])
15+
16+
@unittest.skip("reason for skipping")
17+
def test_run_docs_serve(self):
18+
dp = OpenDbtProject(project_dir=self.DBTTEST_DIR, profiles_dir=self.DBTTEST_DIR)
19+
dp.run(command="docs", args=['serve'])

tests/test_opendbt_project.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,3 @@ def test_run_compile(self):
1515
def test_run_run(self):
1616
dp = OpenDbtProject(project_dir=self.DBTTEST_DIR, profiles_dir=self.DBTTEST_DIR)
1717
dp.run(command="run", args=['--select', 'my_first_dbt_model+'], use_subprocess=True)
18-
19-
def test_run_docs_generate(self):
20-
dp = OpenDbtProject(project_dir=self.DBTTEST_DIR, profiles_dir=self.DBTTEST_DIR)
21-
dp.run(command="docs", args=["generate"])

0 commit comments

Comments
 (0)