Skip to content

Commit cb1b7a5

Browse files
author
Doug Greiman
committed
Explicitly pass individual arg values instead of argparse object.
1 parent e5dab4c commit cb1b7a5

2 files changed

Lines changed: 34 additions & 31 deletions

File tree

scripts/gen_dockerfile.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,14 @@
108108
)
109109

110110

111-
def get_app_config(raw_config, args):
111+
def get_app_config(raw_config, base_image, config_file, source_dir):
112112
"""Read and validate the application runtime configuration.
113113
114114
Args:
115115
raw_config (dict): deserialized app.yaml
116-
args (argparse.Namespace): command line flags
116+
base_image (str): Docker image name to build on top of
117+
config_file (str): Path to user's app.yaml (might be <service-name>.yaml)
118+
source_dir (str): Directory container user's source code
117119
118120
Returns:
119121
AppConfig: valid configuration
@@ -122,7 +124,7 @@ def get_app_config(raw_config, args):
122124
if not isinstance(raw_config, dict):
123125
raise ValueError(
124126
'Expected {} contents to be of type "dict", but found type "{}"'.
125-
format(args.config, type(raw_config)))
127+
format(config_file, type(raw_config)))
126128

127129
entrypoint = validation_utils.get_field_value(raw_config, 'entrypoint', str)
128130
if not PRINTABLE_REGEX.match(entrypoint):
@@ -139,10 +141,7 @@ def get_app_config(raw_config, args):
139141

140142
# Examine user's files
141143
has_requirements_txt = os.path.isfile(
142-
os.path.join(args.source_dir, 'requirements.txt'))
143-
144-
# Compute base image name and Dockerfile contents
145-
base_image = args.base_image
144+
os.path.join(source_dir, 'requirements.txt'))
146145

147146
return AppConfig(
148147
base_image=base_image,
@@ -191,46 +190,49 @@ def generate_files(app_config):
191190
}
192191

193192

194-
def gen_dockerfile(args):
193+
def gen_dockerfile(base_image, config_file, source_dir):
195194
"""Write a Dockerfile and helper files for an application.
196195
197196
Args:
198-
args (argparse.Namespace): command line flags
197+
base_image (str): Docker image name to build on top of
198+
config_file (str): Path to user's app.yaml (might be <service-name>.yaml)
199+
source_dir (str): Directory container user's source code
199200
"""
200201
# Read yaml file. Does not currently support multiple services
201202
# with configuration filenames besides app.yaml
202-
with io.open(args.config, 'r', encoding='utf8') as yaml_config_file:
203+
with io.open(config_file, 'r', encoding='utf8') as yaml_config_file:
203204
raw_config = yaml.load(yaml_config_file)
204205

205-
# Determine configuration
206-
app_config = get_app_config(raw_config, args)
206+
# Determine complete configuration
207+
app_config = get_app_config(raw_config, base_image, config_file,
208+
source_dir)
207209

208210
# Generate list of filenames and their textual contents
209211
files = generate_files(app_config)
210212

211213
# Write files
212214
for filename, contents in files.items():
213-
full_filename = os.path.join(args.source_dir, filename)
215+
full_filename = os.path.join(source_dir, filename)
214216
with io.open(full_filename, 'w', encoding='utf8') as outfile:
215217
outfile.write(contents)
216218

217219

218220
def parse_args(argv):
219221
"""Parse and validate command line flags"""
220222
parser = argparse.ArgumentParser()
223+
parser.add_argument(
224+
'--base-image',
225+
type=functools.partial(
226+
validation_utils.validate_arg_regex, flag_regex=IMAGE_REGEX),
227+
default='gcr.io/google-appengine/python:latest',
228+
help='Name of Docker image to use as base')
221229
parser.add_argument(
222230
'--config',
223231
type=functools.partial(
224232
validation_utils.validate_arg_regex, flag_regex=PRINTABLE_REGEX),
225233
default='app.yaml',
226234
help='Path to application configuration file'
227235
)
228-
parser.add_argument(
229-
'--base-image',
230-
type=functools.partial(
231-
validation_utils.validate_arg_regex, flag_regex=IMAGE_REGEX),
232-
default='gcr.io/google-appengine/python:latest',
233-
help='Name of Docker image to use as base')
234236
parser.add_argument(
235237
'--source-dir',
236238
type=functools.partial(
@@ -243,7 +245,7 @@ def parse_args(argv):
243245

244246
def main():
245247
args = parse_args(sys.argv)
246-
gen_dockerfile(args)
248+
gen_dockerfile(args.base_image, args.config, args.source_dir)
247249

248250

249251
if __name__ == '__main__':

scripts/gen_dockerfile_test.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ def compare_file(self, filename, dir1, dir2):
4949
self.assertMultiLineEqual(contents1, contents2, msg)
5050

5151
def test_get_app_config(self):
52-
args = argparse.Namespace(
53-
config='some_config_file',
54-
base_image='some_image_name',
55-
source_dir='some_source_dir')
52+
config_file = 'some_config_file'
53+
base_image = 'some_image_name'
54+
source_dir = 'some_source_dir'
5655

5756
valid_cases = (
5857
# Basic app.yaml
@@ -93,7 +92,9 @@ def test_get_app_config(self):
9392
raw_app_config = yaml.safe_load(app_yaml)
9493
with unittest.mock.patch.object(
9594
os.path, 'isfile', return_value=isfile):
96-
actual = gen_dockerfile.get_app_config(raw_app_config, args)
95+
actual = gen_dockerfile.get_app_config(
96+
raw_app_config, base_image, config_file,
97+
source_dir)
9798
for key, value in expected.items():
9899
self.assertEqual(getattr(actual, key), value)
99100

@@ -110,7 +111,9 @@ def test_get_app_config(self):
110111
with self.subTest(invalid_case=invalid_case):
111112
raw_app_config = yaml.safe_load(invalid_case)
112113
with self.assertRaises(ValueError):
113-
gen_dockerfile.get_app_config(raw_app_config, args)
114+
gen_dockerfile.get_app_config(
115+
raw_app_config, base_image, config_file,
116+
source_dir)
114117

115118
def test_generate_files(self):
116119
base = gen_dockerfile.AppConfig(
@@ -165,12 +168,10 @@ def test_gen_dockerfile(self):
165168
# Copy sample app to writable temp dir, and generate Dockerfile.
166169
config_dir = os.path.join(temp_dir, 'config')
167170
shutil.copytree(app_dir, config_dir)
168-
args = argparse.Namespace(
169-
config=os.path.join(config_dir, 'app.yaml'),
171+
gen_dockerfile.gen_dockerfile(
170172
base_image='gcr.io/google-appengine/python',
171-
source_dir=config_dir,
172-
)
173-
gen_dockerfile.gen_dockerfile(args)
173+
config_file=os.path.join(config_dir, 'app.yaml'),
174+
source_dir=config_dir)
174175

175176
# Compare against golden files
176177
golden_dir = os.path.join(self.testdata_dir, app + '_golden')

0 commit comments

Comments
 (0)