@@ -34,7 +34,9 @@ def parse_env(env):
3434 exports = []
3535 name = None
3636 value = None
37+
3738 if re .search ("=" ,env ):
39+
3840 pieces = [p for p in re .split ("( |\\ \" .*?\\ \" |'.*?')" , env ) if p .strip ()]
3941 while len (pieces ) > 0 :
4042 contender = pieces .pop (0 )
@@ -50,27 +52,32 @@ def parse_env(env):
5052 else :
5153 value = "%s %s" % (value ,contender )
5254 exports .append (join_env (name ,value ))
55+
5356 # otherwise, the rule is one per line
5457 else :
5558 name ,value = re .split (' ' ,env ,1 )
5659 exports = ["export %s=%s" % (name ,value )]
5760 environment = []
61+
5862 # Clean exports, make sure we aren't using
5963 for export in exports :
6064 export = export .strip ('\n ' ).replace ('"' ,"" ).replace ("'" ,"" )
6165 environment .append (export )
6266 export = 'echo "\n %s" >> /environment' % (export )
6367 environment .append (export )
68+
6469 return "%s\n " % "\n " .join (environment )
6570
6671
6772def join_env (name ,value ):
73+
6874 # If it's the end of the string, we don't want a space
6975 if re .search ("=$" ,name ):
7076 if value != None :
7177 return "export %s%s" % (name ,value )
7278 else :
7379 return "export %s" % (name )
80+
7481 if value != None :
7582 return "export %s %s" % (name ,value )
7683 return "export %s" % (name )
@@ -183,7 +190,9 @@ def get_mapping():
183190 build spec section. Note - this currently ignores lines that we don't know what to do with
184191 in the context of Singularity (eg, EXPOSE, LABEL, USER, VOLUME, STOPSIGNAL, escape,
185192 MAINTAINER)
193+
186194 :: note
195+
187196 each KEY of the mapping should be a command start in the Dockerfile (eg, RUN)
188197 for each corresponding value, there should be a dictionary with the following:
189198
@@ -195,6 +204,7 @@ def get_mapping():
195204 external files. It should suffice for our purposes (for now) to use the same function
196205 (parse_add) until evidence for a major difference is determined.
197206 '''
207+
198208 # Docker : Singularity
199209 add_command = {"section" : "%post" ,"fun" : parse_add , "json" : True }
200210 copy_command = {"section" : "%post" , "fun" : parse_add , "json" : True }
@@ -205,6 +215,7 @@ def get_mapping():
205215 run_command = {"section" : "%post" , "json" : True }
206216 workdir_command = {"section" : "%post" ,"fun" : parse_workdir , "json" : False }
207217 entry_command = {"section" : "%post" , "fun" : parse_entry , "json" : True }
218+
208219 return {"ADD" : add_command ,
209220 "COPY" :copy_command ,
210221 "CMD" :cmd_command ,
@@ -263,19 +274,23 @@ def organize_sections(lines,mapping=None):
263274 '''
264275 if mapping == None :
265276 mapping = get_mapping ()
277+
266278 sections = dict ()
267279 startre = "|" .join (["^%s" % x for x in mapping .keys ()])
268280 command = None
269281 name = None
282+
270283 for l in range (0 ,len (lines )):
271284 line = lines [l ]
285+
272286 # If it's a newline or comment, just add it to post
273287 if line == "\n " or re .search ("^#" ,line ):
274288 sections = parse_section (name = "%post" ,
275289 command = line ,
276290 mapping = mapping ,
277291 sections = sections )
278292 elif re .search (startre ,line ):
293+
279294 # Parse the last section, and start over
280295 if command != None and name != None :
281296 sections = parse_section (name = name ,
@@ -284,8 +299,10 @@ def organize_sections(lines,mapping=None):
284299 sections = sections )
285300 name ,command = line .split (" " ,1 )
286301 else :
302+
287303 # We have a continuation of the last command or an empty line
288304 command = "%s\n %s" % (command ,line )
305+
289306 return sections
290307
291308def parse_section (sections ,name ,command ,mapping = None ):
@@ -300,17 +317,21 @@ def parse_section(sections,name,command,mapping=None):
300317 '''
301318 if mapping == None :
302319 mapping = get_mapping ()
320+
303321 if name in mapping :
304322 build_section = mapping [name ]['section' ]
323+
305324 # Can the command potentially be json (a list?)
306325 if mapping [name ]['json' ]:
307326 try :
308327 command = " " .join (json .loads (command ))
309328 except :
310329 pass
330+
311331 # Do we need to pass it through a function first?
312332 if 'fun' in mapping [name ]:
313333 command = mapping [name ]['fun' ](command )
334+
314335 # Add to our dictionary of sections!
315336 if build_section not in sections :
316337 sections [build_section ] = [command ]
@@ -326,20 +347,26 @@ def print_sections(sections,mapping=None):
326347 :param sections: output from organize_sections
327348 :mapping: a dictionary mapping Docker commands to Singularity sections
328349 '''
350+
329351 if mapping == None :
330352 mapping = get_mapping ()
353+
331354 finished_spec = None
332355 ordering = ['bootstrap' ,"From" ,"%runscript" ,"%post" ]
356+
333357 for section in ordering :
358+
334359 # Was the section found in the file?
335360 if section in sections :
336361 content = "" .join (sections [section ])
362+
337363 # A single command, intended to go after a colon (yaml)
338364 if not re .search ("^%" ,section ):
339365 content = "%s:%s" % (section ,content )
340366 else :
341367 # A list of things to join, after the section header
342368 content = "%s\n %s" % (section ,content )
369+
343370 # Are we adding the first line?
344371 if finished_spec == None :
345372 finished_spec = content
0 commit comments