Several flavors for an Android application (Eclipse ADT) -
there android application developed under , built eclipse/adt. have make exist in 2 flavours: market version (with google libraries purchase support) , version customer n (without google play stuff custom features).
i cannot refactor library because break version control history. important not break version control , make sure bugs fixed in common part fixed in both flavors. important keep directory structure (src/ res/ libs/). cannot introduce flag because requirement leave no trace of custom features in market binary.
if wanted remove custom features manually, (1) remove source files (both java , resources) and (2) comment out lines in other source files (again, both java , xml resources).
how make application exist in 2 versions (flavours) different feature sets?
another version of same script. better suited large number of configurations. supports ancestor configurations. cannot set configurations linux , master separately: must define linux-master. happens because disables or enables each configuration knows, no configuration left untouched. otoh, can have 2 copies of script, e.g. 1 selecting os , selecting user access level.
setconfig.1.py:
#!/usr/bin/python # coding: utf-8 # configuration list format is: 1 configuration on each line, first configuration name names of parent configurations, e.g.: # guest # basic # advanced basic # superuser advanced # linux # windows # customer1 superuser linux # customer2 basic windows # customer3 guest windows configurations = """ guest basic advanced basic superuser advanced linux windows customer1 superuser linux customer2 basic windows customer3 guest windows """ import argparse import os import re #set false debugging = true verbose = true configlist = filter(none,map(lambda l:l.split(), configurations.split('\n'))) configparents = { l[0] : l l in configlist } ancestorsets = {} def findancestors(name,visited,tovisit): visited.add(name) in tovisit: if not in visited: visited.update(findancestors(a,visited,configparents[a])) return visited c,p in configparents.iteritems(): ancestorsets[c] = findancestors(c,set(),p) # in file 'fname', # find text matching "before oldtext after" (all occurrences) , # replace 'oldtext' 'newtext' (all occurrences). # if 'mandatory' true, raise exception if no replacements made. def filereplace(fname,before,newtext,after,oldtextpattern=r"[\w.]+",mandatory=true): open(fname, 'r+') f: read_data = f.read() pattern = r"("+re.escape(before)+r")"+oldtextpattern+"("+re.escape(after)+r")" replacement = r"\g<1>"+newtext+r"\g<2>" new_data,replacements_made = re.subn(pattern,replacement,read_data,flags=re.multiline) if replacements_made , really: if new_data!=read_data: f.seek(0) f.truncate() f.write(new_data) if verbose: print "patching ",fname," (",replacements_made," occurrence" + ("s" if 1!=replacements_made else ""),")",newtext,("-- no changes" if new_data==read_data else "-- ***changed***") elif replacements_made: print "\n\n\n\n" print fname,":" print new_data elif mandatory: raise exception("cannot patch file: "+fname+" ["+newtext+"] instead of '"+before+"{"+oldtextpattern+"}"+after+"'") def enableconfiginfile(flavour,fname, enable=true): if enable: symbol=r"*" oldsymbol=re.escape("/") else: symbol=r"/" oldsymbol=re.escape("*") filereplace(fname, "/*"+flavour+"{",symbol,"/",oldtextpattern=oldsymbol, mandatory=false) def enableconfiginxmlfile(flavour,fname, enable=true): if enable: startsymbol=r"<!--" endsymbol=r"-->" oldstartsymbol=re.escape("x!==") oldendsymbol=re.escape("==x") else: startsymbol=r"x!==" endsymbol=r"==x" oldstartsymbol=re.escape("<!--") oldendsymbol=re.escape("-->") filereplace(fname, "<!--"+flavour+"{", endsymbol, "", oldtextpattern=oldendsymbol, mandatory=false) filereplace(fname, "", startsymbol, "}"+flavour+"-->", oldtextpattern=oldstartsymbol, mandatory=false) def enableconfig(flavour, enable=true): root, dirs, files in os.walk(".", topdown=true): # ignore version control directories # why .hg- , .git- ? need hide .hg or .git programs `meld`. # (`meld` ignores .hg if finds .git) if '.svn' in dirs: dirs.remove('.svn') if '.svn-' in dirs: dirs.remove('.svn-') if '.hg' in dirs: dirs.remove('.hg') if '.hg-' in dirs: dirs.remove('.hg-') if '.git' in dirs: dirs.remove('.git') if '.git-' in dirs: dirs.remove('.git-') name in files: if name.endswith('.java'): enableconfiginfile(flavour, os.path.join(root, name), enable) elif name.endswith('.xml'): enableconfiginxmlfile(flavour, os.path.join(root, name), enable) if __name__ == "__main__": parser = argparse.argumentparser() c in configlist: thisconf = c[0] parser.add_argument('--'+thisconf, dest='conf', action='store_const', const=thisconf, help='configure as: '+thisconf) args = parser.parse_args() if args.conf none: parser.print_help() else: print "setting configuration: "+args.conf toenable = ancestorsets[args.conf] c in ancestorsets: print ("enabling " if c in toenable else "disabling ")+c enableconfig(c, enable=c in toenable)
Comments
Post a Comment