112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
|
import os
|
||
|
import shutil
|
||
|
|
||
|
import dbt.config
|
||
|
import dbt.clients.system
|
||
|
from dbt.version import _get_adapter_plugin_names
|
||
|
from dbt.adapters.factory import load_plugin, get_include_paths
|
||
|
|
||
|
from dbt.logger import GLOBAL_LOGGER as logger
|
||
|
|
||
|
from dbt.include.starter_project import PACKAGE_PATH as starter_project_directory
|
||
|
|
||
|
from dbt.task.base import BaseTask
|
||
|
|
||
|
DOCS_URL = 'https://docs.getdbt.com/docs/configure-your-profile'
|
||
|
SLACK_URL = 'https://community.getdbt.com/'
|
||
|
|
||
|
# This file is not needed for the starter project but exists for finding the resource path
|
||
|
IGNORE_FILES = ["__init__.py", "__pycache__"]
|
||
|
|
||
|
ON_COMPLETE_MESSAGE = """
|
||
|
Your new dbt project "{project_name}" was created! If this is your first time
|
||
|
using dbt, you'll need to set up your profiles.yml file -- this file will tell dbt how
|
||
|
to connect to your database. You can find this file by running:
|
||
|
|
||
|
{open_cmd} {profiles_path}
|
||
|
|
||
|
For more information on how to configure the profiles.yml file,
|
||
|
please consult the dbt documentation here:
|
||
|
|
||
|
{docs_url}
|
||
|
|
||
|
One more thing:
|
||
|
|
||
|
Need help? Don't hesitate to reach out to us via GitHub issues or on Slack:
|
||
|
|
||
|
{slack_url}
|
||
|
|
||
|
Happy modeling!
|
||
|
"""
|
||
|
|
||
|
|
||
|
class InitTask(BaseTask):
|
||
|
def copy_starter_repo(self, project_name):
|
||
|
logger.debug("Starter project path: " + starter_project_directory)
|
||
|
shutil.copytree(starter_project_directory, project_name,
|
||
|
ignore=shutil.ignore_patterns(*IGNORE_FILES))
|
||
|
|
||
|
def create_profiles_dir(self, profiles_dir):
|
||
|
if not os.path.exists(profiles_dir):
|
||
|
msg = "Creating dbt configuration folder at {}"
|
||
|
logger.info(msg.format(profiles_dir))
|
||
|
dbt.clients.system.make_directory(profiles_dir)
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
def create_profiles_file(self, profiles_file, sample_adapter):
|
||
|
# Line below raises an exception if the specified adapter is not found
|
||
|
load_plugin(sample_adapter)
|
||
|
adapter_path = get_include_paths(sample_adapter)[0]
|
||
|
sample_profiles_path = adapter_path / 'sample_profiles.yml'
|
||
|
|
||
|
if not sample_profiles_path.exists():
|
||
|
logger.debug(f"No sample profile found for {sample_adapter}, skipping")
|
||
|
return False
|
||
|
|
||
|
if not os.path.exists(profiles_file):
|
||
|
msg = "With sample profiles.yml for {}"
|
||
|
logger.info(msg.format(sample_adapter))
|
||
|
shutil.copyfile(sample_profiles_path, profiles_file)
|
||
|
return True
|
||
|
|
||
|
return False
|
||
|
|
||
|
def get_addendum(self, project_name, profiles_path):
|
||
|
open_cmd = dbt.clients.system.open_dir_cmd()
|
||
|
|
||
|
return ON_COMPLETE_MESSAGE.format(
|
||
|
open_cmd=open_cmd,
|
||
|
project_name=project_name,
|
||
|
profiles_path=profiles_path,
|
||
|
docs_url=DOCS_URL,
|
||
|
slack_url=SLACK_URL
|
||
|
)
|
||
|
|
||
|
def run(self):
|
||
|
project_dir = self.args.project_name
|
||
|
sample_adapter = self.args.adapter
|
||
|
if not sample_adapter:
|
||
|
try:
|
||
|
# pick first one available, often postgres
|
||
|
sample_adapter = next(_get_adapter_plugin_names())
|
||
|
except StopIteration:
|
||
|
logger.debug("No adapters installed, skipping")
|
||
|
|
||
|
profiles_dir = dbt.config.PROFILES_DIR
|
||
|
profiles_file = os.path.join(profiles_dir, 'profiles.yml')
|
||
|
|
||
|
self.create_profiles_dir(profiles_dir)
|
||
|
if sample_adapter:
|
||
|
self.create_profiles_file(profiles_file, sample_adapter)
|
||
|
|
||
|
if os.path.exists(project_dir):
|
||
|
raise RuntimeError("directory {} already exists!".format(
|
||
|
project_dir
|
||
|
))
|
||
|
|
||
|
self.copy_starter_repo(project_dir)
|
||
|
|
||
|
addendum = self.get_addendum(project_dir, profiles_dir)
|
||
|
logger.info(addendum)
|