|
|
@ -1,46 +1,75 @@ |
|
|
|
#!/usr/bin/env python |
|
|
|
#!/usr/bin/env python |
|
|
|
|
|
|
|
|
|
|
|
# NOTE: It would be nice to be able to use py2exe to compile this for Windows (since it produces |
|
|
|
|
|
|
|
# a single EXE instead of the morass of files cx-freeze generates) but py2exe only works up to |
|
|
|
|
|
|
|
# Python 3.4, since the byte code format changed after that. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys |
|
|
|
import sys |
|
|
|
import os |
|
|
|
import os |
|
|
|
|
|
|
|
import shutil |
|
|
|
import glob |
|
|
|
import glob |
|
|
|
|
|
|
|
import getopt |
|
|
|
from cx_Freeze import setup , Executable |
|
|
|
from cx_Freeze import setup , Executable |
|
|
|
|
|
|
|
|
|
|
|
from constants import * |
|
|
|
from constants import * |
|
|
|
|
|
|
|
import asl_cards |
|
|
|
|
|
|
|
|
|
|
|
base_dir = os.path.split( os.path.abspath(__file__) )[ 0 ] |
|
|
|
base_dir = os.path.split( os.path.abspath(__file__) )[ 0 ] |
|
|
|
os.chdir( base_dir ) |
|
|
|
build_dir = os.path.join( base_dir , "build" ) |
|
|
|
|
|
|
|
|
|
|
|
import asl_cards |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------- |
|
|
|
# --------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
def get_extra_files( fspec ) : |
|
|
|
def get_extra_files() : |
|
|
|
"""Locate extra files to include in the release.""" |
|
|
|
"""Get the extra files to include in the release.""" |
|
|
|
|
|
|
|
def globfiles( fspec ) : |
|
|
|
fnames = glob.glob( fspec ) |
|
|
|
fnames = glob.glob( fspec ) |
|
|
|
return zip( fnames , fnames ) |
|
|
|
return zip( fnames , fnames ) |
|
|
|
|
|
|
|
|
|
|
|
# initialize |
|
|
|
|
|
|
|
extra_files = [] |
|
|
|
extra_files = [] |
|
|
|
extra_files.extend( get_extra_files( "index/*.txt" ) ) |
|
|
|
extra_files.extend( globfiles( "index/*.txt" ) ) |
|
|
|
extra_files.extend( get_extra_files( "resources/*.ico" ) ) |
|
|
|
extra_files.extend( globfiles( "resources/*.ico" ) ) |
|
|
|
extra_files.extend( get_extra_files( "resources/*.png" ) ) |
|
|
|
extra_files.extend( globfiles( "resources/*.png" ) ) |
|
|
|
extra_files.extend( get_extra_files( "ui/*.ui" ) ) |
|
|
|
extra_files.extend( globfiles( "ui/*.ui" ) ) |
|
|
|
extra_files.append( ( "asl_cards/natinfo" , "asl_cards/natinfo" ) ) |
|
|
|
extra_files.append( ( "asl_cards/natinfo" , "asl_cards/natinfo" ) ) |
|
|
|
if sys.platform == "win32" : |
|
|
|
if sys.platform == "win32" : |
|
|
|
# workaround a cx-freeze bug (already fixed, but after 5.0.1 was released) :wall: >:-/ |
|
|
|
# workaround a cx-freeze bug (already fixed, but after 5.0.1 was released) :wall: >:-/ |
|
|
|
# https://bitbucket.org/anthony_tuininga/cx_freeze/issues/207/sqlite3dll-not-shipped |
|
|
|
# https://bitbucket.org/anthony_tuininga/cx_freeze/issues/207/sqlite3dll-not-shipped |
|
|
|
extra_files.append( os.path.join( sys.base_prefix , "DLLs" , "sqlite3.dll" ) ) |
|
|
|
extra_files.append( os.path.join( sys.base_prefix , "DLLs" , "sqlite3.dll" ) ) |
|
|
|
|
|
|
|
return extra_files |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# parse the command-line options |
|
|
|
|
|
|
|
output_fname = None |
|
|
|
|
|
|
|
cleanup = True |
|
|
|
|
|
|
|
opts,args = getopt.getopt( sys.argv[1:] , "o:" , ["output=","noclean"] ) |
|
|
|
|
|
|
|
for opt,val in opts : |
|
|
|
|
|
|
|
if opt in ["-o","--output"] : |
|
|
|
|
|
|
|
output_fname = val |
|
|
|
|
|
|
|
elif opt in ["--noclean"] : |
|
|
|
|
|
|
|
cleanup = False |
|
|
|
|
|
|
|
else : |
|
|
|
|
|
|
|
raise RuntimeError( "Unknown argument: {}".format( opt ) ) |
|
|
|
|
|
|
|
if not output_fname : |
|
|
|
|
|
|
|
raise RuntimeError( "No output file was specified." ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# figure out the format of the release archive |
|
|
|
|
|
|
|
formats = { ".zip": "zip" , ".tar.gz": "gztar" , ".tar.bz": "bztar" , ".tar": "tar" } |
|
|
|
|
|
|
|
output_fmt = None |
|
|
|
|
|
|
|
for extn,fmt in formats.items() : |
|
|
|
|
|
|
|
if output_fname.endswith( extn ) : |
|
|
|
|
|
|
|
output_fmt = fmt |
|
|
|
|
|
|
|
output_fname2 = output_fname[ : -len(extn) ] |
|
|
|
|
|
|
|
break |
|
|
|
|
|
|
|
if not output_fmt : |
|
|
|
|
|
|
|
raise RuntimeError( "Unknown output format." ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# initialize the build options |
|
|
|
build_options = { |
|
|
|
build_options = { |
|
|
|
"packages": [ "os" , "sqlalchemy" ] , |
|
|
|
"packages": [ "os" , "sqlalchemy" ] , |
|
|
|
"excludes": [ "tkinter" ] , |
|
|
|
"excludes": [ "tkinter" ] , |
|
|
|
"include_files": extra_files , |
|
|
|
"include_files": get_extra_files() , |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# freeze the application |
|
|
|
# freeze the application |
|
|
|
|
|
|
|
# NOTE: It would be nice to be able to use py2exe to compile this for Windows (since it produces |
|
|
|
|
|
|
|
# a single EXE instead of the morass of files cx-freeze generates) but py2exe only works up to |
|
|
|
|
|
|
|
# Python 3.4, since the byte code format changed after that. |
|
|
|
# NOTE: We can't call the Linux binary "asl_cards", since we need a directory of the same name :-/ |
|
|
|
# NOTE: We can't call the Linux binary "asl_cards", since we need a directory of the same name :-/ |
|
|
|
target = Executable( |
|
|
|
target = Executable( |
|
|
|
"main.py" , |
|
|
|
"main.py" , |
|
|
@ -48,6 +77,12 @@ target = Executable( |
|
|
|
targetName = "aslcards.exe" if sys.platform == "win32" else "aslcards" , |
|
|
|
targetName = "aslcards.exe" if sys.platform == "win32" else "aslcards" , |
|
|
|
icon = os.path.join( base_dir , "resources/app.ico" ) , |
|
|
|
icon = os.path.join( base_dir , "resources/app.ico" ) , |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
if os.path.isdir( build_dir ) : |
|
|
|
|
|
|
|
shutil.rmtree( build_dir ) |
|
|
|
|
|
|
|
os.chdir( base_dir ) |
|
|
|
|
|
|
|
del sys.argv[1:] |
|
|
|
|
|
|
|
sys.argv.append( "build" ) |
|
|
|
|
|
|
|
# nb: cx-freeze doesn't report compile errors or anything like that :-/ |
|
|
|
setup( |
|
|
|
setup( |
|
|
|
name = APP_NAME , |
|
|
|
name = APP_NAME , |
|
|
|
version = APP_VERSION , |
|
|
|
version = APP_VERSION , |
|
|
@ -57,3 +92,20 @@ setup( |
|
|
|
} , |
|
|
|
} , |
|
|
|
executables = [ target ] |
|
|
|
executables = [ target ] |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# create the release archive |
|
|
|
|
|
|
|
print( "Generating release archive: {}".format( output_fname ) ) |
|
|
|
|
|
|
|
files = os.listdir( build_dir ) |
|
|
|
|
|
|
|
if len(files) != 1 : |
|
|
|
|
|
|
|
raise RuntimeError( "Unexpected freeze output." ) |
|
|
|
|
|
|
|
dname = os.path.join( build_dir , files[0] ) |
|
|
|
|
|
|
|
os.chdir( dname ) |
|
|
|
|
|
|
|
shutil.make_archive( output_fname2 , output_fmt ) |
|
|
|
|
|
|
|
file_size = os.path.getsize( output_fname ) |
|
|
|
|
|
|
|
print( "- Done: {0:.1f} MB".format( float(file_size) / 1024 / 1024 ) ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# clean up |
|
|
|
|
|
|
|
if cleanup : |
|
|
|
|
|
|
|
os.chdir( base_dir ) # so we can delete the build directory :-/ |
|
|
|
|
|
|
|
shutil.rmtree( build_dir ) |
|
|
|