@@ -264,77 +264,89 @@ def discard_from_buffer(self, key: str):
264
264
del self .data ["files" ][key ]
265
265
return self
266
266
267
- def raise_on_empty_entrypoint (self ):
267
+ def require_entrypoint (self ) -> str :
268
+ """
269
+ If self.entrypoint is a string, return it; if it is None, raise an exception.
270
+ """
268
271
if self .entrypoint is None :
269
272
raise RSConnectException ("A valid entrypoint must be provided." )
270
- return self
273
+ return self .entrypoint
274
+
275
+ def get_manifest_files (self ) -> dict [str , ManifestDataFile ]:
276
+ new_data_files : dict [str , ManifestDataFile ] = {}
277
+ deploy_dir : str
278
+
279
+ entrypoint = self .require_entrypoint ()
280
+ if self .deploy_dir is not None :
281
+ deploy_dir = self .deploy_dir
282
+ elif entrypoint is not None and isfile (entrypoint ):
283
+ deploy_dir = dirname (entrypoint )
284
+ else :
285
+ # TODO: This branch might be an error case. Need to investigate.
286
+ deploy_dir = entrypoint
271
287
272
- @property
273
- def flattened_data (self ):
274
- self .raise_on_empty_entrypoint ()
275
- new_data_files = {}
276
- deploy_dir = dirname (self .entrypoint ) if isfile (self .entrypoint ) else self .entrypoint
277
- deploy_dir = self .deploy_dir or deploy_dir
278
288
for path in self .data ["files" ]:
279
289
rel_path = relpath (path , deploy_dir )
280
290
manifestPath = Path (rel_path ).as_posix ()
281
291
new_data_files [manifestPath ] = self .data ["files" ][path ]
282
292
return new_data_files
283
293
284
- @property
285
- def flattened_buffer (self ) -> dict [str , str ]:
286
- self .raise_on_empty_entrypoint ()
294
+ def get_manifest_files_from_buffer (self ) -> dict [str , str ]:
287
295
new_buffer : dict [str , str ] = {}
288
- deploy_dir = dirname (self .entrypoint ) if isfile (self .entrypoint ) else self .entrypoint
289
- deploy_dir = self .deploy_dir or deploy_dir
296
+ deploy_dir : str
297
+
298
+ entrypoint = self .require_entrypoint ()
299
+ if self .deploy_dir is not None :
300
+ deploy_dir = self .deploy_dir
301
+ elif entrypoint is not None and isfile (entrypoint ):
302
+ deploy_dir = dirname (entrypoint )
303
+ else :
304
+ # TODO: This branch might be an error case. Need to investigate.
305
+ deploy_dir = entrypoint
306
+
290
307
for k , v in self .buffer .items ():
291
308
rel_path = relpath (k , deploy_dir )
292
309
manifestPath = Path (rel_path ).as_posix ()
293
310
new_buffer [manifestPath ] = v
294
311
return new_buffer
295
312
296
- @property
297
- def flattened_entrypoint (self ):
298
- self .raise_on_empty_entrypoint ()
299
- return relpath (self .entrypoint , dirname (self .entrypoint ))
313
+ def get_relative_entrypoint (self ) -> str :
314
+ entrypoint = self .require_entrypoint ()
315
+ return basename (entrypoint )
300
316
301
- @property
302
- def flattened_primary_html (self ):
317
+ def get_flattened_primary_html (self ):
303
318
if self .primary_html is None :
304
319
raise RSConnectException ("A valid primary_html must be provided." )
305
320
return relpath (self .primary_html , dirname (self .primary_html ))
306
321
307
- @property
308
- def flattened_copy (self ):
309
- self .raise_on_empty_entrypoint ()
322
+ def get_flattened_copy (self ):
310
323
new_manifest = deepcopy (self )
311
- new_manifest .data ["files" ] = self .flattened_data
312
- new_manifest .buffer = self .flattened_buffer
313
- new_manifest .entrypoint = self .flattened_entrypoint
324
+ new_manifest .data ["files" ] = self .get_manifest_files ()
325
+ new_manifest .buffer = self .get_manifest_files_from_buffer ()
326
+ new_manifest .entrypoint = self .get_relative_entrypoint ()
314
327
if self .primary_html :
315
- new_manifest .primary_html = self .flattened_primary_html
328
+ new_manifest .primary_html = self .get_flattened_primary_html ()
316
329
return new_manifest
317
330
318
331
319
332
class Bundle :
320
333
def __init__ (self ) -> None :
321
334
self .file_paths : set [str ] = set ()
322
335
self .buffer : dict [str , str ] = {}
323
- self .deploy_dir : str | None = None
324
336
325
337
def add_file (self , filepath : str ) -> None :
326
338
self .file_paths .add (filepath )
327
339
328
340
def discard_file (self , filepath : str ) -> None :
329
341
self .file_paths .discard (filepath )
330
342
331
- def to_file (self , flatten_to_deploy_dir : bool = True ) -> typing .IO [bytes ]:
343
+ def to_file (self , deploy_dir : str ) -> typing .IO [bytes ]:
332
344
bundle_file = tempfile .TemporaryFile (prefix = "rsc_bundle" )
333
345
with tarfile .open (mode = "w:gz" , fileobj = bundle_file ) as bundle :
334
346
for fp in self .file_paths :
335
347
if Path (fp ).name in self .buffer :
336
348
continue
337
- rel_path = Path (fp ).relative_to (self . deploy_dir ) if flatten_to_deploy_dir else None
349
+ rel_path = Path (fp ).relative_to (deploy_dir )
338
350
logger .log (VERBOSE , "Adding file: %s" , fp )
339
351
bundle .add (fp , arcname = rel_path )
340
352
for k , v in self .buffer .items ():
@@ -1062,20 +1074,21 @@ def make_html_bundle(
1062
1074
1063
1075
if manifest .data .get ("files" ) is None :
1064
1076
raise RSConnectException ("No valid files were found for the manifest." )
1077
+ if manifest .deploy_dir is None :
1078
+ raise RSConnectException ("deploy_dir was not set for the manifest." )
1065
1079
1066
1080
bundle = Bundle ()
1067
1081
for f in manifest .data ["files" ]:
1068
1082
if f in manifest .buffer :
1069
1083
continue
1070
1084
bundle .add_file (f )
1071
- for k , v in manifest .flattened_buffer .items ():
1085
+ for k , v in manifest .get_manifest_files_from_buffer () .items ():
1072
1086
bundle .add_to_buffer (k , v )
1073
1087
1074
- manifest_flattened_copy_data = manifest .flattened_copy .data
1088
+ manifest_flattened_copy_data = manifest .get_flattened_copy () .data
1075
1089
bundle .add_to_buffer ("manifest.json" , json .dumps (manifest_flattened_copy_data , indent = 2 ))
1076
- bundle .deploy_dir = manifest .deploy_dir
1077
1090
1078
- return bundle .to_file ()
1091
+ return bundle .to_file (manifest . deploy_dir )
1079
1092
1080
1093
1081
1094
def create_file_list (
@@ -1255,22 +1268,23 @@ def make_voila_bundle(
1255
1268
1256
1269
if manifest .data .get ("files" ) is None :
1257
1270
raise RSConnectException ("No valid files were found for the manifest." )
1271
+ if manifest .deploy_dir is None :
1272
+ raise RSConnectException ("deploy_dir was not set for the manifest." )
1258
1273
1259
1274
bundle = Bundle ()
1260
1275
for f in manifest .data ["files" ]:
1261
1276
if f in manifest .buffer :
1262
1277
continue
1263
1278
bundle .add_file (f )
1264
- for k , v in manifest .flattened_buffer .items ():
1279
+ for k , v in manifest .get_manifest_files_from_buffer () .items ():
1265
1280
bundle .add_to_buffer (k , v )
1266
1281
1267
- manifest_flattened_copy_data = manifest .flattened_copy .data
1282
+ manifest_flattened_copy_data = manifest .get_flattened_copy () .data
1268
1283
if multi_notebook and "metadata" in manifest_flattened_copy_data :
1269
1284
manifest_flattened_copy_data ["metadata" ]["entrypoint" ] = ""
1270
1285
bundle .add_to_buffer ("manifest.json" , json .dumps (manifest_flattened_copy_data , indent = 2 ))
1271
- bundle .deploy_dir = manifest .deploy_dir
1272
1286
1273
- return bundle .to_file ()
1287
+ return bundle .to_file (manifest . deploy_dir )
1274
1288
1275
1289
1276
1290
def make_api_bundle (
@@ -1969,8 +1983,12 @@ def write_voila_manifest_json(
1969
1983
env_management_r = env_management_r ,
1970
1984
multi_notebook = multi_notebook ,
1971
1985
)
1986
+
1987
+ if manifest .entrypoint is None :
1988
+ raise RSConnectException ("Voila manifest requires an entrypoint." )
1989
+
1972
1990
deploy_dir = dirname (manifest .entrypoint ) if isfile (manifest .entrypoint ) else manifest .entrypoint
1973
- manifest_flattened_copy_data = manifest .flattened_copy .data
1991
+ manifest_flattened_copy_data = manifest .get_flattened_copy () .data
1974
1992
if multi_notebook and "metadata" in manifest_flattened_copy_data :
1975
1993
manifest_flattened_copy_data ["metadata" ]["entrypoint" ] = ""
1976
1994
manifest_path = join (deploy_dir , "manifest.json" )
0 commit comments