Skip to content

Commit

Permalink
Added class PyInstHook.
Browse files Browse the repository at this point in the history
  • Loading branch information
BuvinJ committed Mar 17, 2020
1 parent 44eb047 commit 63136b2
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 12 deletions.
1 change: 1 addition & 0 deletions distbuilder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from distbuilder.py_installer import \
PyInstallerConfig \
, PyInstSpec \
, PyInstHook \
, WindowsExeVersionInfo \
, buildExecutable \
, makePyInstSpec
Expand Down
2 changes: 1 addition & 1 deletion distbuilder/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.7.6.15"
__version__ = "0.7.7.0"
41 changes: 40 additions & 1 deletion distbuilder/py_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
PYINST_BIN_NAME = util.normBinaryName( "pyinstaller" )
PYINST_MAKESPEC_BIN_NAME = util.normBinaryName( "pyi-makespec" )

PYINST_ROOT_PKG_NAME = "PyInstaller"

SPEC_EXT = ".spec"

BUILD_DIR_PATH = absPath( "build" )
DIST_DIR_PATH = absPath( "dist" )
CACHE_DIR_PATH = absPath( "__pycache__" )

HOOKS_DIR_NAME = "hooks"

__TEMP_NEST_DIR_NAME = "__nested__"

# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -239,7 +243,7 @@ def injectDuplicateDataPatch( self ):
print("Duplicate data patch injected into .spec file...")

def _toLines( self ):
return self.content.split('\n' ) if self.content else []
return self.content.split( '\n' ) if self.content else []

def _fromLines( self, lines ): self.content = '\n'.join( lines )

Expand Down Expand Up @@ -337,6 +341,41 @@ def write( self ):

def debug( self ): print( str(self) )

class PyInstHook( ExecutableScript ) :

def __init__( self, name, script=None ):
ExecutableScript.__init__( self,
name, extension=PY_EXT, shebang=None, script=script )
self.hooksDirPath = None

def __str__( self ): return self.script

def read( self ):
self.__resolveHooksPath()
hookPath = joinPath( self.hooksDirPath, self.fileName() )
if not isFile( hookPath ):
raise Exception(
"PyInstaller hook does not exist: %s" % (hookPath,) )
with open( hookPath, 'rb' ) as f: self.script = f.read()

def write( self ):
self.__resolveHooksPath()
ExecutableScript.write( self, self.hooksDirPath )

def debug( self ): print( str(self) )

def __resolveHooksPath( self ):
if self.hooksDirPath is None:
try:
pgkDir = modulePackagePath( PYINST_ROOT_PKG_NAME )
if pgkDir is None: raise Exception()
hooksDir = joinPath( pgkDir, HOOKS_DIR_NAME )
if isDir( hooksDir ): self.hooksDirPath = hooksDir
else: raise Exception()
except:
raise Exception(
"PyInstaller hooks directory could not be resolved." )

# -----------------------------------------------------------------------------
def buildExecutable( name=None, entryPointPy=None,
pyInstConfig=PyInstallerConfig(),
Expand Down
2 changes: 1 addition & 1 deletion distbuilder/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ def debug( self ):
if self.script: print( str(self) )

def fileName( self ):
return joinExt( self.rootName,self.extension )
return joinExt( self.rootName, self.extension )

def write( self, dirPath ):
if self.script is None : return
Expand Down
39 changes: 39 additions & 0 deletions docs/ConfigClasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,45 @@ Object Methods:
_injectLine( injection, lineNo )
_parseAssigments()

## PyInstHook

Objects of this type are used for PyInstaller "hook" script
creation, and programmatic manipulation.
Such hooks are executed during a PyInstaller build process
when an import is encountered with a matching hook name. The purpose
of a hook is to help PyInstaller find and collect resources
it would otherwise not know to include in the bundle.

Hooks are commonly installed by third party libraries for use across your
python environment whenever you employ PyInstaller. It is
also possible to use custom hooks locally during a given a
build process (though it is **not** seemingly possible to explictly
*override* one which is registered for the system on the whole.)

The most typical use case of this class is to replace **bad hooks**
installed on your system, or to simply revise them for some
additional custom need.

For more on hooks, see:
[Understanding PyInstaller Hooks](https://pyinstaller.readthedocs.io/en/stable/hooks.html)

Constructor:

PyInstHook( name, script=None )

Attributes & default values:

name = <required, omit .py extension>
script = None
hooksDirPath = None <auto resolve>

Object Methods:

read()
write()
debug()
fileName()

## WindowsExeVersionInfo

Objects of this type define meta data branded into Windows
Expand Down
14 changes: 8 additions & 6 deletions docs/HighLevel.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ information on the types of objects generated by this factory class.

Note that this class is NOT intended to have a one-to-one correspondence
for **every** attribute within all of the configuration objects it can generate.
If that were provided, this class would become an overwhelmingly bloated monster!
Only the more commonly needed (and/or shared) attributes are provided on this level. You
must manipulate the config objects generated by the factory *directly* if you need to
access their more extended features.
must manipulate those config objects generated by the factory *directly* if you need to
access their more extended features. Typically, you will want to access those
objects from a "callback" function within a derived "Process" class implementation.

Constructor:

Expand Down Expand Up @@ -406,7 +408,7 @@ package programs developed within the Qt C++ libraries / framework.

See the [Qt C++ Integration](QtCpp.md) document for more information.

## Process Classes
## Process Classes Overview

Many build scripts will follow the same essential
logic flow, to produce analogous distributions.
Expand All @@ -423,7 +425,7 @@ each more powerful (and complex) then the prior:
- [PyToBinInstallerProcess](#pytobininstallerprocess)
- [RobustInstallerProcess](#robustinstallerprocess)

### PyToBinPackageProcess
## PyToBinPackageProcess

This "simple" process class converts a program written in Python
scripts into a stand-alone executable binary. It additionally
Expand Down Expand Up @@ -571,7 +573,7 @@ manipulations of the results.
These notable object attributes will now be set for you to potentially use at this
stage: `binDir`, `binPath`.

### PyToBinInstallerProcess
## PyToBinInstallerProcess

A PyToBinInstallerProcess process *contains* a
[PyToBinPackageProcess](#pytobinpackageprocess)
Expand Down Expand Up @@ -683,7 +685,7 @@ Before running the process to build the installer, that master config object
is passed through this function, where you can manipulate it as needed for your
implementation.

### RobustInstallerProcess
## RobustInstallerProcess

A RobustInstallerProcess is the most advanced and intricate of these processes.
It exposes details of the build process that [PyToBinInstallerProcess](#pytobininstallerprocess)
Expand Down
6 changes: 3 additions & 3 deletions docs/LowLevel.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ program, invoke the buildExecutable function:
created. Note that the default destination path is
the root directory of the package, using the same
file name. To package a resource within a sub directory,
or with an alternate name, you must *either* explictly provide
or with an alternate name, you must *either* explictly provide
a full (relative) destination path *or* **use the
"shortcut value" `True` to indicate both the source
and destination are relative and exactly the same**.
"shortcut value" `True` to indicate the source
and destination are the same relative paths**.

**distDirs**: An (optional) list of directories to
create within the package. Note distResources
Expand Down

0 comments on commit 63136b2

Please sign in to comment.