0

I am using Python 3.5.2 and PyInstaller 3.2 to turn a small PyQt5 application into a standalone utility for internal use. PyInstaller is necessary because most of the team hasn't installed Python3.

I would like to put the Subversion properties of the WC from which the utility is generated into the utility's Help->About dialog, but I'm struggling to figure out a reasonable approach for doing this.

If I were using a different build environment I would define a template file and have TortoiseSVN's SubWCRev generate a source file as a pre-build step. At the moment however the "build" of my utility is the one-step process of invoking PyInstaller on a modified spec file. I'd prefer to keep it this way.

I suspect that it is possible to write a custom hook for PyInstaller that will get the required properties from the working copy, (equivalents of WCRANGE, WCMODS and WCMIXED, probably using pysvn), and embed them as properties of the generated exe. Has anyone done this, or is this approach completely wrong?

Thank you.

Wasi
  • 1,473
  • 3
  • 16
  • 32
Peter Du
  • 548
  • 1
  • 10
  • 20
  • See [this answer](http://stackoverflow.com/a/1812153/960558) for good pythonic-way and maybe the whole topic – Lazy Badger Oct 25 '16 at 07:16
  • @LazyBadger The problem with the approach as outlined by the solution that you linked to is that the revision will be the revision of the particular `__init__.py` file. TortoiseSVN's SubWCRev program will look for the highest and lowest version of all the files in the working copy, hence you get a range of revision numbers rather than the single revision of a particular file, and I'm particularly looking to replicate that behaviour. – Peter Du Oct 25 '16 at 07:26
  • @Wasi Are there guidelines for standard formatting of questions? It's not obvious to me why your formatting is better than the original plain text. – Peter Du Oct 25 '16 at 07:27
  • [Check out this link](http://stackoverflow.com/help/formatting) – Wasi Oct 25 '16 at 07:57
  • @PeterDu - it's not a problem (at least for me) to commit file in every revision – Lazy Badger Oct 25 '16 at 08:09
  • @PeterDu - and your OS and used SVN tool is ...? – Lazy Badger Oct 25 '16 at 08:10
  • @lazybadger It's windows 7 & TortoiseSVN most of the time. I think that I can extract the properties with pysvn if I have the opportunity to run python in the context of pyinstaller. The question then is how to make the result accessible to the application. – Peter Du Oct 25 '16 at 10:00
  • Why not run SubWCRev in post-commit hook and write proper file, which you can `import NAME` in your code? – Lazy Badger Oct 25 '16 at 11:05
  • Another opportunities - 1) hack [python-versioneer](https://blog.mozilla.org/warner/2012/01/31/version-string-management-in-python-introducing-python-versioneer/) in order to work with SVN (here pysvn will be needed) 2) sync SVN-repo with Git-clone and use Verioneer as is – Lazy Badger Oct 25 '16 at 11:08
  • @lazybadger yes something like the suggestion with the post commit hook. I'm thinking that i can do it as part of the pyinstaller build rather than post commit. I'll try along those lines tomorrow and let you know how I went. – Peter Du Oct 25 '16 at 11:44
  • The `.spec` file is actually a python script. You can add a piece of code before the Analysis block to extract the information from SVN and write it in a text file. You can then add that to the build at the datas block. – Repiklis Oct 25 '16 at 13:17
  • @Repiklis that seems promising. Will report back tomorrow. – Peter Du Oct 25 '16 at 13:20

1 Answers1

0

Thanks for the tips. The direction described by @Repiklis provided a good solution. I've added the following code at the top of my .spec file for PyInstaller

import json
import os
import pysvn

os.remove('versioninfo.json')

c = pysvn.Client()
entry = c.info('.')
statuses = c.status('.')

mods = [{'Path': s.path,
            'CommitRevision': s.entry.commit_revision.number,
            'UpdateRevision': s.entry.revision.number,
            'Kind': str(s.entry.kind),
            'Status': str(s.text_status if
                            s.entry.kind == pysvn.node_kind.file
                        else
                            s.prop_status)
        } for s in statuses if (
    s.text_status != pysvn.wc_status_kind.none
    and 
    s.text_status != pysvn.wc_status_kind.unversioned
    and 
    s.text_status != pysvn.wc_status_kind.ignored
)]

version = {'URL': entry.url, 'Source': mods}

with open('versioninfo.json', 'w') as fp:
    json.dump(version, fp=fp, sort_keys=True, indent=4)

Later there is

a = Analysis(...
             datas=[..., ('versioninfo.json', '.')]
             ...
            )

Finally, the json file is loaded in the Help->About dialog, and presented to the user.

Thanks everyone.

Community
  • 1
  • 1
Peter Du
  • 548
  • 1
  • 10
  • 20