Add env file parsing

This commit is contained in:
Jake Howard 2018-12-18 21:42:23 +00:00
parent 9870342567
commit ae5b3eeefb
Signed by: jake
GPG key ID: 57AFB45680EDD477
6 changed files with 26 additions and 1 deletions

View file

@ -1,9 +1,12 @@
import re import re
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import List from typing import Dict, List
from dotenv import dotenv_values
PROCFILE_LOCATIONS = ["Procfile", "etc/environments/development/Procfile"] PROCFILE_LOCATIONS = ["Procfile", "etc/environments/development/Procfile"]
ENVFILE_LOCATIONS = [".env", "etc/environments/development/env"]
PROCFILE_LINE = re.compile(r"^([A-Za-z0-9_]+):\s*(.+)$") PROCFILE_LINE = re.compile(r"^([A-Za-z0-9_]+):\s*(.+)$")
@ -26,11 +29,13 @@ def parse_procfile_processes(project, procfile_lines):
class Project: class Project:
root: Path root: Path
processes: List["Process"] = field(default_factory=list) processes: List["Process"] = field(default_factory=list)
env: Dict[str, str] = field(default_factory=dict)
def __post_init__(self): def __post_init__(self):
self.root = Path(self.root) self.root = Path(self.root)
assert self.exists() assert self.exists()
self.processes = self.read_processes() self.processes = self.read_processes()
self.read_envfiles()
def read_processes(self): def read_processes(self):
for location in PROCFILE_LOCATIONS: for location in PROCFILE_LOCATIONS:
@ -40,6 +45,12 @@ class Project:
return list(parse_procfile_processes(self, f.readlines())) return list(parse_procfile_processes(self, f.readlines()))
return [] return []
def read_envfiles(self):
for location in ENVFILE_LOCATIONS:
envfile_path = self.root.joinpath(location)
if envfile_path.exists():
self.env.update(dotenv_values(envfile_path))
def exists(self): def exists(self):
return self.root.exists() and self.root.is_dir() return self.root.exists() and self.root.is_dir()

View file

@ -70,6 +70,7 @@ async def run_process_command(project: Project, process: Process):
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
env={ env={
**os.environ, **os.environ,
**project.env,
"PYTHONUNBUFFERED": "1", "PYTHONUNBUFFERED": "1",
"CATFISH_IDENT": process.ident, "CATFISH_IDENT": process.ident,
"PATH": "{}:{}".format( "PATH": "{}:{}".format(

View file

@ -0,0 +1 @@
FOO=bar

View file

@ -19,6 +19,7 @@ setup(
"ujson", "ujson",
"pyzmq", "pyzmq",
"aiofiles", "aiofiles",
"python-dotenv",
], ],
entry_points=""" entry_points="""
[console_scripts] [console_scripts]

View file

@ -34,6 +34,9 @@ class ProjectTestCase(BaseTestCase):
def test_name(self): def test_name(self):
self.assertEqual(self.project.name, "example") self.assertEqual(self.project.name, "example")
def test_read_environment(self):
self.assertEqual(self.project.env["FOO"], "bar")
class ProcessTestCase(BaseTestCase): class ProcessTestCase(BaseTestCase):
def setUp(self): def setUp(self):

View file

@ -34,6 +34,14 @@ class ProcessWorkerTestCase(BaseWorkerTestCase):
env = psutil.Process(response["pid"]).environ() env = psutil.Process(response["pid"]).environ()
self.assertEqual(env["PYTHONUNBUFFERED"], "1") self.assertEqual(env["PYTHONUNBUFFERED"], "1")
self.assertEqual(env["CATFISH_IDENT"], self.process.ident) self.assertEqual(env["CATFISH_IDENT"], self.process.ident)
self.assertEqual(env["FOO"], "bar")
def test_additional_path(self):
response = send_to_server(
PayloadType.PROCESS,
{"path": str(self.project.root), "process": str(self.process.name)},
)
env = psutil.Process(response["pid"]).environ()
path_dirs = env["PATH"].split(":") path_dirs = env["PATH"].split(":")
for path in self.project.get_extra_path(): for path in self.project.get_extra_path():
self.assertIn(str(path), path_dirs) self.assertIn(str(path), path_dirs)