We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
dbt trying to parse tags in analyses even when wrapped in `raw` tags
## Issue

### Steps to Reproduce
1. Put an unknown tag within `raw` tags in a sql file, in your _analysis_ directory (note that the bug doesn't occur in a model).
```
{% raw %}
{% form %}
date_part:
    type: select
    default: day
    options: [hour, day, week, month]
{% endform %}
{% endraw %}
```
2. run `dbt compile`

### Expected Result
The following should be compiled:
```
{% form %}
date_part:
    type: select
    default: day
    options: [hour, day, week, month]
{% endform %}
```


### Actual Result
Error on compilation:
```bash
Found 0 models, 0 tests, 0 archives, 1 analyses, 122 macros, 2 operations, 0 seed files

10:56:47 | Concurrency: 1 threads (target='dev')
10:56:47 |
Encountered an error:
Runtime Error
  Compilation Error in analysis form_tag (analysis/analysis/form_tag.sql)
    Encountered unknown tag 'form'.
      line 2
        {% form %}
```

### System information
OS: MacOS Mojave
Python 3.7.1
dbt 0.12.1




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dbt/compilation.py`
Content:
```
1 import itertools
2 import os
3 import json
4 from collections import OrderedDict, defaultdict
5 import sqlparse
6 
7 import dbt.utils
8 import dbt.include
9 import dbt.tracking
10 
11 from dbt.utils import get_materialization, NodeType, is_type
12 
13 from dbt.linker import Linker
14 
15 import dbt.compat
16 import dbt.context.runtime
17 import dbt.contracts.project
18 import dbt.exceptions
19 import dbt.flags
20 import dbt.loader
21 import dbt.config
22 from dbt.contracts.graph.compiled import CompiledNode, CompiledGraph
23 
24 from dbt.clients.system import write_json
25 from dbt.logger import GLOBAL_LOGGER as logger
26 
27 graph_file_name = 'graph.gpickle'
28 manifest_file_name = 'manifest.json'
29 
30 
31 def print_compile_stats(stats):
32     names = {
33         NodeType.Model: 'models',
34         NodeType.Test: 'tests',
35         NodeType.Archive: 'archives',
36         NodeType.Analysis: 'analyses',
37         NodeType.Macro: 'macros',
38         NodeType.Operation: 'operations',
39         NodeType.Seed: 'seed files',
40     }
41 
42     results = {k: 0 for k in names.keys()}
43     results.update(stats)
44 
45     stat_line = ", ".join(
46         ["{} {}".format(ct, names.get(t)) for t, ct in results.items()])
47 
48     logger.info("Found {}".format(stat_line))
49 
50 
51 def _add_prepended_cte(prepended_ctes, new_cte):
52     for dct in prepended_ctes:
53         if dct['id'] == new_cte['id']:
54             dct['sql'] = new_cte['sql']
55             return
56     prepended_ctes.append(new_cte)
57 
58 
59 def _extend_prepended_ctes(prepended_ctes, new_prepended_ctes):
60     for new_cte in new_prepended_ctes:
61         _add_prepended_cte(prepended_ctes, new_cte)
62 
63 
64 def prepend_ctes(model, manifest):
65     model, _, manifest = recursively_prepend_ctes(model, manifest)
66 
67     return (model, manifest)
68 
69 
70 def recursively_prepend_ctes(model, manifest):
71     if model.extra_ctes_injected:
72         return (model, model.extra_ctes, manifest)
73 
74     if dbt.flags.STRICT_MODE:
75         # ensure that all the nodes in this manifest are compiled
76         CompiledGraph(**manifest.to_flat_graph())
77 
78     prepended_ctes = []
79 
80     for cte in model.extra_ctes:
81         cte_id = cte['id']
82         cte_to_add = manifest.nodes.get(cte_id)
83         cte_to_add, new_prepended_ctes, manifest = recursively_prepend_ctes(
84             cte_to_add, manifest)
85 
86         _extend_prepended_ctes(prepended_ctes, new_prepended_ctes)
87         new_cte_name = '__dbt__CTE__{}'.format(cte_to_add.get('name'))
88         sql = ' {} as (\n{}\n)'.format(new_cte_name, cte_to_add.compiled_sql)
89         _add_prepended_cte(prepended_ctes, {'id': cte_id, 'sql': sql})
90 
91     model.prepend_ctes(prepended_ctes)
92 
93     manifest.nodes[model.unique_id] = model
94 
95     return (model, prepended_ctes, manifest)
96 
97 
98 class Compiler(object):
99     def __init__(self, config):
100         self.config = config
101 
102     def initialize(self):
103         dbt.clients.system.make_directory(self.config.target_path)
104         dbt.clients.system.make_directory(self.config.modules_path)
105 
106     def compile_node(self, node, manifest, extra_context=None):
107         if extra_context is None:
108             extra_context = {}
109 
110         logger.debug("Compiling {}".format(node.get('unique_id')))
111 
112         data = node.to_dict()
113         data.update({
114             'compiled': False,
115             'compiled_sql': None,
116             'extra_ctes_injected': False,
117             'extra_ctes': [],
118             'injected_sql': None,
119         })
120         compiled_node = CompiledNode(**data)
121 
122         context = dbt.context.runtime.generate(
123             compiled_node, self.config, manifest)
124         context.update(extra_context)
125 
126         compiled_node.compiled_sql = dbt.clients.jinja.get_rendered(
127             node.get('raw_sql'),
128             context,
129             node)
130 
131         compiled_node.compiled = True
132 
133         injected_node, _ = prepend_ctes(compiled_node, manifest)
134 
135         should_wrap = {NodeType.Test, NodeType.Analysis, NodeType.Operation}
136         if injected_node.resource_type in should_wrap:
137             # data tests get wrapped in count(*)
138             # TODO : move this somewhere more reasonable
139             if 'data' in injected_node.tags and \
140                is_type(injected_node, NodeType.Test):
141                 injected_node.wrapped_sql = (
142                     "select count(*) from (\n{test_sql}\n) sbq").format(
143                         test_sql=injected_node.injected_sql)
144             else:
145                 # don't wrap schema tests or analyses.
146                 injected_node.wrapped_sql = injected_node.injected_sql
147 
148         elif is_type(injected_node, NodeType.Archive):
149             # unfortunately we do everything automagically for
150             # archives. in the future it'd be nice to generate
151             # the SQL at the parser level.
152             pass
153 
154         elif(is_type(injected_node, NodeType.Model) and
155              get_materialization(injected_node) == 'ephemeral'):
156             pass
157 
158         else:
159             injected_node.wrapped_sql = None
160 
161         return injected_node
162 
163     def write_manifest_file(self, manifest):
164         """Write the manifest file to disk.
165 
166         manifest should be a Manifest.
167         """
168         filename = manifest_file_name
169         manifest_path = os.path.join(self.config.target_path, filename)
170         write_json(manifest_path, manifest.serialize())
171 
172     def write_graph_file(self, linker):
173         filename = graph_file_name
174         graph_path = os.path.join(self.config.target_path, filename)
175         linker.write_graph(graph_path)
176 
177     def link_node(self, linker, node, manifest):
178         linker.add_node(node.unique_id)
179 
180         linker.update_node_data(
181             node.unique_id,
182             node.to_dict())
183 
184         for dependency in node.depends_on_nodes:
185             if manifest.nodes.get(dependency):
186                 linker.dependency(
187                     node.unique_id,
188                     (manifest.nodes.get(dependency).unique_id))
189 
190             else:
191                 dbt.exceptions.dependency_not_found(node, dependency)
192 
193     def link_graph(self, linker, manifest):
194         for node in manifest.nodes.values():
195             self.link_node(linker, node, manifest)
196 
197         cycle = linker.find_cycles()
198 
199         if cycle:
200             raise RuntimeError("Found a cycle: {}".format(cycle))
201 
202     def get_all_projects(self):
203         all_projects = {self.config.project_name: self.config}
204         dependency_projects = dbt.utils.dependency_projects(self.config)
205 
206         for project_cfg in dependency_projects:
207             name = project_cfg.project_name
208             all_projects[name] = project_cfg
209 
210         if dbt.flags.STRICT_MODE:
211             dbt.contracts.project.ProjectList(**all_projects)
212 
213         return all_projects
214 
215     def _check_resource_uniqueness(cls, manifest):
216         names_resources = {}
217         alias_resources = {}
218 
219         for resource, node in manifest.nodes.items():
220             if node.resource_type not in NodeType.refable():
221                 continue
222 
223             name = node.name
224             alias = "{}.{}".format(node.schema, node.alias)
225 
226             existing_node = names_resources.get(name)
227             if existing_node is not None:
228                 dbt.exceptions.raise_duplicate_resource_name(
229                         existing_node, node)
230 
231             existing_alias = alias_resources.get(alias)
232             if existing_alias is not None:
233                 dbt.exceptions.raise_ambiguous_alias(
234                         existing_alias, node)
235 
236             names_resources[name] = node
237             alias_resources[alias] = node
238 
239     def compile(self):
240         linker = Linker()
241 
242         all_projects = self.get_all_projects()
243 
244         manifest = dbt.loader.GraphLoader.load_all(self.config, all_projects)
245 
246         self.write_manifest_file(manifest)
247 
248         self._check_resource_uniqueness(manifest)
249 
250         resource_fqns = manifest.get_resource_fqns()
251         self.config.warn_for_unused_resource_config_paths(resource_fqns,
252                                                           manifest.disabled)
253 
254         self.link_graph(linker, manifest)
255 
256         stats = defaultdict(int)
257 
258         for node_name, node in itertools.chain(
259                 manifest.nodes.items(),
260                 manifest.macros.items()):
261             stats[node.resource_type] += 1
262 
263         self.write_graph_file(linker)
264         print_compile_stats(stats)
265 
266         return manifest, linker
267
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dbt/compilation.py b/dbt/compilation.py
--- a/dbt/compilation.py
+++ b/dbt/compilation.py
@@ -132,7 +132,7 @@
 
         injected_node, _ = prepend_ctes(compiled_node, manifest)
 
-        should_wrap = {NodeType.Test, NodeType.Analysis, NodeType.Operation}
+        should_wrap = {NodeType.Test, NodeType.Operation}
         if injected_node.resource_type in should_wrap:
             # data tests get wrapped in count(*)
             # TODO : move this somewhere more reasonable

{"golden_diff": "diff --git a/dbt/compilation.py b/dbt/compilation.py\n--- a/dbt/compilation.py\n+++ b/dbt/compilation.py\n@@ -132,7 +132,7 @@\n \n         injected_node, _ = prepend_ctes(compiled_node, manifest)\n \n-        should_wrap = {NodeType.Test, NodeType.Analysis, NodeType.Operation}\n+        should_wrap = {NodeType.Test, NodeType.Operation}\n         if injected_node.resource_type in should_wrap:\n             # data tests get wrapped in count(*)\n             # TODO : move this somewhere more reasonable\n", "issue": "dbt trying to parse tags in analyses even when wrapped in `raw` tags\n## Issue\r\n\r\n### Steps to Reproduce\r\n1. Put an unknown tag within `raw` tags in a sql file, in your _analysis_ directory (note that the bug doesn't occur in a model).\r\n```\r\n{% raw %}\r\n{% form %}\r\ndate_part:\r\n    type: select\r\n    default: day\r\n    options: [hour, day, week, month]\r\n{% endform %}\r\n{% endraw %}\r\n```\r\n2. run `dbt compile`\r\n\r\n### Expected Result\r\nThe following should be compiled:\r\n```\r\n{% form %}\r\ndate_part:\r\n    type: select\r\n    default: day\r\n    options: [hour, day, week, month]\r\n{% endform %}\r\n```\r\n\r\n\r\n### Actual Result\r\nError on compilation:\r\n```bash\r\nFound 0 models, 0 tests, 0 archives, 1 analyses, 122 macros, 2 operations, 0 seed files\r\n\r\n10:56:47 | Concurrency: 1 threads (target='dev')\r\n10:56:47 |\r\nEncountered an error:\r\nRuntime Error\r\n  Compilation Error in analysis form_tag (analysis/analysis/form_tag.sql)\r\n    Encountered unknown tag 'form'.\r\n      line 2\r\n        {% form %}\r\n```\r\n\r\n### System information\r\nOS: MacOS Mojave\r\nPython 3.7.1\r\ndbt 0.12.1\r\n\r\n\r\n\n", "before_files": [{"content": "import itertools\nimport os\nimport json\nfrom collections import OrderedDict, defaultdict\nimport sqlparse\n\nimport dbt.utils\nimport dbt.include\nimport dbt.tracking\n\nfrom dbt.utils import get_materialization, NodeType, is_type\n\nfrom dbt.linker import Linker\n\nimport dbt.compat\nimport dbt.context.runtime\nimport dbt.contracts.project\nimport dbt.exceptions\nimport dbt.flags\nimport dbt.loader\nimport dbt.config\nfrom dbt.contracts.graph.compiled import CompiledNode, CompiledGraph\n\nfrom dbt.clients.system import write_json\nfrom dbt.logger import GLOBAL_LOGGER as logger\n\ngraph_file_name = 'graph.gpickle'\nmanifest_file_name = 'manifest.json'\n\n\ndef print_compile_stats(stats):\n    names = {\n        NodeType.Model: 'models',\n        NodeType.Test: 'tests',\n        NodeType.Archive: 'archives',\n        NodeType.Analysis: 'analyses',\n        NodeType.Macro: 'macros',\n        NodeType.Operation: 'operations',\n        NodeType.Seed: 'seed files',\n    }\n\n    results = {k: 0 for k in names.keys()}\n    results.update(stats)\n\n    stat_line = \", \".join(\n        [\"{} {}\".format(ct, names.get(t)) for t, ct in results.items()])\n\n    logger.info(\"Found {}\".format(stat_line))\n\n\ndef _add_prepended_cte(prepended_ctes, new_cte):\n    for dct in prepended_ctes:\n        if dct['id'] == new_cte['id']:\n            dct['sql'] = new_cte['sql']\n            return\n    prepended_ctes.append(new_cte)\n\n\ndef _extend_prepended_ctes(prepended_ctes, new_prepended_ctes):\n    for new_cte in new_prepended_ctes:\n        _add_prepended_cte(prepended_ctes, new_cte)\n\n\ndef prepend_ctes(model, manifest):\n    model, _, manifest = recursively_prepend_ctes(model, manifest)\n\n    return (model, manifest)\n\n\ndef recursively_prepend_ctes(model, manifest):\n    if model.extra_ctes_injected:\n        return (model, model.extra_ctes, manifest)\n\n    if dbt.flags.STRICT_MODE:\n        # ensure that all the nodes in this manifest are compiled\n        CompiledGraph(**manifest.to_flat_graph())\n\n    prepended_ctes = []\n\n    for cte in model.extra_ctes:\n        cte_id = cte['id']\n        cte_to_add = manifest.nodes.get(cte_id)\n        cte_to_add, new_prepended_ctes, manifest = recursively_prepend_ctes(\n            cte_to_add, manifest)\n\n        _extend_prepended_ctes(prepended_ctes, new_prepended_ctes)\n        new_cte_name = '__dbt__CTE__{}'.format(cte_to_add.get('name'))\n        sql = ' {} as (\\n{}\\n)'.format(new_cte_name, cte_to_add.compiled_sql)\n        _add_prepended_cte(prepended_ctes, {'id': cte_id, 'sql': sql})\n\n    model.prepend_ctes(prepended_ctes)\n\n    manifest.nodes[model.unique_id] = model\n\n    return (model, prepended_ctes, manifest)\n\n\nclass Compiler(object):\n    def __init__(self, config):\n        self.config = config\n\n    def initialize(self):\n        dbt.clients.system.make_directory(self.config.target_path)\n        dbt.clients.system.make_directory(self.config.modules_path)\n\n    def compile_node(self, node, manifest, extra_context=None):\n        if extra_context is None:\n            extra_context = {}\n\n        logger.debug(\"Compiling {}\".format(node.get('unique_id')))\n\n        data = node.to_dict()\n        data.update({\n            'compiled': False,\n            'compiled_sql': None,\n            'extra_ctes_injected': False,\n            'extra_ctes': [],\n            'injected_sql': None,\n        })\n        compiled_node = CompiledNode(**data)\n\n        context = dbt.context.runtime.generate(\n            compiled_node, self.config, manifest)\n        context.update(extra_context)\n\n        compiled_node.compiled_sql = dbt.clients.jinja.get_rendered(\n            node.get('raw_sql'),\n            context,\n            node)\n\n        compiled_node.compiled = True\n\n        injected_node, _ = prepend_ctes(compiled_node, manifest)\n\n        should_wrap = {NodeType.Test, NodeType.Analysis, NodeType.Operation}\n        if injected_node.resource_type in should_wrap:\n            # data tests get wrapped in count(*)\n            # TODO : move this somewhere more reasonable\n            if 'data' in injected_node.tags and \\\n               is_type(injected_node, NodeType.Test):\n                injected_node.wrapped_sql = (\n                    \"select count(*) from (\\n{test_sql}\\n) sbq\").format(\n                        test_sql=injected_node.injected_sql)\n            else:\n                # don't wrap schema tests or analyses.\n                injected_node.wrapped_sql = injected_node.injected_sql\n\n        elif is_type(injected_node, NodeType.Archive):\n            # unfortunately we do everything automagically for\n            # archives. in the future it'd be nice to generate\n            # the SQL at the parser level.\n            pass\n\n        elif(is_type(injected_node, NodeType.Model) and\n             get_materialization(injected_node) == 'ephemeral'):\n            pass\n\n        else:\n            injected_node.wrapped_sql = None\n\n        return injected_node\n\n    def write_manifest_file(self, manifest):\n        \"\"\"Write the manifest file to disk.\n\n        manifest should be a Manifest.\n        \"\"\"\n        filename = manifest_file_name\n        manifest_path = os.path.join(self.config.target_path, filename)\n        write_json(manifest_path, manifest.serialize())\n\n    def write_graph_file(self, linker):\n        filename = graph_file_name\n        graph_path = os.path.join(self.config.target_path, filename)\n        linker.write_graph(graph_path)\n\n    def link_node(self, linker, node, manifest):\n        linker.add_node(node.unique_id)\n\n        linker.update_node_data(\n            node.unique_id,\n            node.to_dict())\n\n        for dependency in node.depends_on_nodes:\n            if manifest.nodes.get(dependency):\n                linker.dependency(\n                    node.unique_id,\n                    (manifest.nodes.get(dependency).unique_id))\n\n            else:\n                dbt.exceptions.dependency_not_found(node, dependency)\n\n    def link_graph(self, linker, manifest):\n        for node in manifest.nodes.values():\n            self.link_node(linker, node, manifest)\n\n        cycle = linker.find_cycles()\n\n        if cycle:\n            raise RuntimeError(\"Found a cycle: {}\".format(cycle))\n\n    def get_all_projects(self):\n        all_projects = {self.config.project_name: self.config}\n        dependency_projects = dbt.utils.dependency_projects(self.config)\n\n        for project_cfg in dependency_projects:\n            name = project_cfg.project_name\n            all_projects[name] = project_cfg\n\n        if dbt.flags.STRICT_MODE:\n            dbt.contracts.project.ProjectList(**all_projects)\n\n        return all_projects\n\n    def _check_resource_uniqueness(cls, manifest):\n        names_resources = {}\n        alias_resources = {}\n\n        for resource, node in manifest.nodes.items():\n            if node.resource_type not in NodeType.refable():\n                continue\n\n            name = node.name\n            alias = \"{}.{}\".format(node.schema, node.alias)\n\n            existing_node = names_resources.get(name)\n            if existing_node is not None:\n                dbt.exceptions.raise_duplicate_resource_name(\n                        existing_node, node)\n\n            existing_alias = alias_resources.get(alias)\n            if existing_alias is not None:\n                dbt.exceptions.raise_ambiguous_alias(\n                        existing_alias, node)\n\n            names_resources[name] = node\n            alias_resources[alias] = node\n\n    def compile(self):\n        linker = Linker()\n\n        all_projects = self.get_all_projects()\n\n        manifest = dbt.loader.GraphLoader.load_all(self.config, all_projects)\n\n        self.write_manifest_file(manifest)\n\n        self._check_resource_uniqueness(manifest)\n\n        resource_fqns = manifest.get_resource_fqns()\n        self.config.warn_for_unused_resource_config_paths(resource_fqns,\n                                                          manifest.disabled)\n\n        self.link_graph(linker, manifest)\n\n        stats = defaultdict(int)\n\n        for node_name, node in itertools.chain(\n                manifest.nodes.items(),\n                manifest.macros.items()):\n            stats[node.resource_type] += 1\n\n        self.write_graph_file(linker)\n        print_compile_stats(stats)\n\n        return manifest, linker\n", "path": "dbt/compilation.py"}], "after_files": [{"content": "import itertools\nimport os\nimport json\nfrom collections import OrderedDict, defaultdict\nimport sqlparse\n\nimport dbt.utils\nimport dbt.include\nimport dbt.tracking\n\nfrom dbt.utils import get_materialization, NodeType, is_type\n\nfrom dbt.linker import Linker\n\nimport dbt.compat\nimport dbt.context.runtime\nimport dbt.contracts.project\nimport dbt.exceptions\nimport dbt.flags\nimport dbt.loader\nimport dbt.config\nfrom dbt.contracts.graph.compiled import CompiledNode, CompiledGraph\n\nfrom dbt.clients.system import write_json\nfrom dbt.logger import GLOBAL_LOGGER as logger\n\ngraph_file_name = 'graph.gpickle'\nmanifest_file_name = 'manifest.json'\n\n\ndef print_compile_stats(stats):\n    names = {\n        NodeType.Model: 'models',\n        NodeType.Test: 'tests',\n        NodeType.Archive: 'archives',\n        NodeType.Analysis: 'analyses',\n        NodeType.Macro: 'macros',\n        NodeType.Operation: 'operations',\n        NodeType.Seed: 'seed files',\n    }\n\n    results = {k: 0 for k in names.keys()}\n    results.update(stats)\n\n    stat_line = \", \".join(\n        [\"{} {}\".format(ct, names.get(t)) for t, ct in results.items()])\n\n    logger.info(\"Found {}\".format(stat_line))\n\n\ndef _add_prepended_cte(prepended_ctes, new_cte):\n    for dct in prepended_ctes:\n        if dct['id'] == new_cte['id']:\n            dct['sql'] = new_cte['sql']\n            return\n    prepended_ctes.append(new_cte)\n\n\ndef _extend_prepended_ctes(prepended_ctes, new_prepended_ctes):\n    for new_cte in new_prepended_ctes:\n        _add_prepended_cte(prepended_ctes, new_cte)\n\n\ndef prepend_ctes(model, manifest):\n    model, _, manifest = recursively_prepend_ctes(model, manifest)\n\n    return (model, manifest)\n\n\ndef recursively_prepend_ctes(model, manifest):\n    if model.extra_ctes_injected:\n        return (model, model.extra_ctes, manifest)\n\n    if dbt.flags.STRICT_MODE:\n        # ensure that all the nodes in this manifest are compiled\n        CompiledGraph(**manifest.to_flat_graph())\n\n    prepended_ctes = []\n\n    for cte in model.extra_ctes:\n        cte_id = cte['id']\n        cte_to_add = manifest.nodes.get(cte_id)\n        cte_to_add, new_prepended_ctes, manifest = recursively_prepend_ctes(\n            cte_to_add, manifest)\n\n        _extend_prepended_ctes(prepended_ctes, new_prepended_ctes)\n        new_cte_name = '__dbt__CTE__{}'.format(cte_to_add.get('name'))\n        sql = ' {} as (\\n{}\\n)'.format(new_cte_name, cte_to_add.compiled_sql)\n        _add_prepended_cte(prepended_ctes, {'id': cte_id, 'sql': sql})\n\n    model.prepend_ctes(prepended_ctes)\n\n    manifest.nodes[model.unique_id] = model\n\n    return (model, prepended_ctes, manifest)\n\n\nclass Compiler(object):\n    def __init__(self, config):\n        self.config = config\n\n    def initialize(self):\n        dbt.clients.system.make_directory(self.config.target_path)\n        dbt.clients.system.make_directory(self.config.modules_path)\n\n    def compile_node(self, node, manifest, extra_context=None):\n        if extra_context is None:\n            extra_context = {}\n\n        logger.debug(\"Compiling {}\".format(node.get('unique_id')))\n\n        data = node.to_dict()\n        data.update({\n            'compiled': False,\n            'compiled_sql': None,\n            'extra_ctes_injected': False,\n            'extra_ctes': [],\n            'injected_sql': None,\n        })\n        compiled_node = CompiledNode(**data)\n\n        context = dbt.context.runtime.generate(\n            compiled_node, self.config, manifest)\n        context.update(extra_context)\n\n        compiled_node.compiled_sql = dbt.clients.jinja.get_rendered(\n            node.get('raw_sql'),\n            context,\n            node)\n\n        compiled_node.compiled = True\n\n        injected_node, _ = prepend_ctes(compiled_node, manifest)\n\n        should_wrap = {NodeType.Test, NodeType.Operation}\n        if injected_node.resource_type in should_wrap:\n            # data tests get wrapped in count(*)\n            # TODO : move this somewhere more reasonable\n            if 'data' in injected_node.tags and \\\n               is_type(injected_node, NodeType.Test):\n                injected_node.wrapped_sql = (\n                    \"select count(*) from (\\n{test_sql}\\n) sbq\").format(\n                        test_sql=injected_node.injected_sql)\n            else:\n                # don't wrap schema tests or analyses.\n                injected_node.wrapped_sql = injected_node.injected_sql\n\n        elif is_type(injected_node, NodeType.Archive):\n            # unfortunately we do everything automagically for\n            # archives. in the future it'd be nice to generate\n            # the SQL at the parser level.\n            pass\n\n        elif(is_type(injected_node, NodeType.Model) and\n             get_materialization(injected_node) == 'ephemeral'):\n            pass\n\n        else:\n            injected_node.wrapped_sql = None\n\n        return injected_node\n\n    def write_manifest_file(self, manifest):\n        \"\"\"Write the manifest file to disk.\n\n        manifest should be a Manifest.\n        \"\"\"\n        filename = manifest_file_name\n        manifest_path = os.path.join(self.config.target_path, filename)\n        write_json(manifest_path, manifest.serialize())\n\n    def write_graph_file(self, linker):\n        filename = graph_file_name\n        graph_path = os.path.join(self.config.target_path, filename)\n        linker.write_graph(graph_path)\n\n    def link_node(self, linker, node, manifest):\n        linker.add_node(node.unique_id)\n\n        linker.update_node_data(\n            node.unique_id,\n            node.to_dict())\n\n        for dependency in node.depends_on_nodes:\n            if manifest.nodes.get(dependency):\n                linker.dependency(\n                    node.unique_id,\n                    (manifest.nodes.get(dependency).unique_id))\n\n            else:\n                dbt.exceptions.dependency_not_found(node, dependency)\n\n    def link_graph(self, linker, manifest):\n        for node in manifest.nodes.values():\n            self.link_node(linker, node, manifest)\n\n        cycle = linker.find_cycles()\n\n        if cycle:\n            raise RuntimeError(\"Found a cycle: {}\".format(cycle))\n\n    def get_all_projects(self):\n        all_projects = {self.config.project_name: self.config}\n        dependency_projects = dbt.utils.dependency_projects(self.config)\n\n        for project_cfg in dependency_projects:\n            name = project_cfg.project_name\n            all_projects[name] = project_cfg\n\n        if dbt.flags.STRICT_MODE:\n            dbt.contracts.project.ProjectList(**all_projects)\n\n        return all_projects\n\n    def _check_resource_uniqueness(cls, manifest):\n        names_resources = {}\n        alias_resources = {}\n\n        for resource, node in manifest.nodes.items():\n            if node.resource_type not in NodeType.refable():\n                continue\n\n            name = node.name\n            alias = \"{}.{}\".format(node.schema, node.alias)\n\n            existing_node = names_resources.get(name)\n            if existing_node is not None:\n                dbt.exceptions.raise_duplicate_resource_name(\n                        existing_node, node)\n\n            existing_alias = alias_resources.get(alias)\n            if existing_alias is not None:\n                dbt.exceptions.raise_ambiguous_alias(\n                        existing_alias, node)\n\n            names_resources[name] = node\n            alias_resources[alias] = node\n\n    def compile(self):\n        linker = Linker()\n\n        all_projects = self.get_all_projects()\n\n        manifest = dbt.loader.GraphLoader.load_all(self.config, all_projects)\n\n        self.write_manifest_file(manifest)\n\n        self._check_resource_uniqueness(manifest)\n\n        resource_fqns = manifest.get_resource_fqns()\n        self.config.warn_for_unused_resource_config_paths(resource_fqns,\n                                                          manifest.disabled)\n\n        self.link_graph(linker, manifest)\n\n        stats = defaultdict(int)\n\n        for node_name, node in itertools.chain(\n                manifest.nodes.items(),\n                manifest.macros.items()):\n            stats[node.resource_type] += 1\n\n        self.write_graph_file(linker)\n        print_compile_stats(stats)\n\n        return manifest, linker\n", "path": "dbt/compilation.py"}]}