1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2026-01-22 14:41:39 +00:00

Merge commit 'a65077f871481ca98ce51810751e66f228cb096a'

# Conflicts:
#	build.py
#	core/pe/iphoto_plist.py
This commit is contained in:
Virgil Dupras
2016-06-05 13:18:33 -04:00
92 changed files with 659 additions and 1514 deletions

189
build.py
View File

@@ -1,6 +1,4 @@
# Created By: Virgil Dupras
# Created On: 2009-12-30
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
@@ -11,7 +9,6 @@ import os
import os.path as op
from optparse import OptionParser
import shutil
import json
import importlib
import compileall
@@ -22,10 +19,10 @@ from hscommon.build import (
add_to_pythonpath, print_and_do, copy_packages, filereplace,
get_module_version, move_all, copy_all, OSXAppStructure,
build_cocoalib_xibless, fix_qt_resource_file, build_cocoa_ext, copy_embeddable_python_dylib,
collect_stdlib_dependencies, copy
collect_stdlib_dependencies
)
from hscommon import loc
from hscommon.plat import ISOSX, ISLINUX
from hscommon.plat import ISOSX
from hscommon.util import ensure_folder, delete_files_with_pattern
def parse_args():
@@ -39,6 +36,14 @@ def parse_args():
'--doc', action='store_true', dest='doc',
help="Build only the help file"
)
parser.add_option(
'--ui', dest='ui',
help="Type of UI to build. 'qt' or 'cocoa'. Default is determined by your system."
)
parser.add_option(
'--dev', action='store_true', dest='dev', default=False,
help="If this flag is set, will configure for dev builds."
)
parser.add_option(
'--loc', action='store_true', dest='loc',
help="Build only localization"
@@ -70,15 +75,11 @@ def parse_args():
(options, args) = parser.parse_args()
return options
def cocoa_app(edition):
app_path = {
'se': 'build/dupeGuru.app',
'me': 'build/dupeGuru ME.app',
'pe': 'build/dupeGuru PE.app',
}[edition]
def cocoa_app():
app_path = 'build/dupeGuru.app'
return OSXAppStructure(app_path)
def build_xibless(edition, dest='cocoa/autogen'):
def build_xibless(dest='cocoa/autogen'):
import xibless
ensure_folder(dest)
FNPAIRS = [
@@ -94,56 +95,50 @@ def build_xibless(edition, dest='cocoa/autogen'):
for srcname, dstname in FNPAIRS:
xibless.generate(
op.join('cocoa', 'base', 'ui', srcname), op.join(dest, dstname),
localizationTable='Localizable', args={'edition': edition}
)
if edition == 'pe':
xibless.generate(
'cocoa/pe/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
localizationTable='Localizable'
)
else:
xibless.generate(
'cocoa/base/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
localizationTable='Localizable'
)
# XXX This is broken
assert False
# if edition == 'pe':
# xibless.generate(
# 'cocoa/pe/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
# localizationTable='Localizable'
# )
# else:
# xibless.generate(
# 'cocoa/base/ui/details_panel.py', op.join(dest, 'DetailsPanel_UI'),
# localizationTable='Localizable'
# )
def build_cocoa(edition, dev):
def build_cocoa(dev):
print("Creating OS X app structure")
ed = lambda s: s.format(edition)
app = cocoa_app(edition)
app_version = get_module_version(ed('core_{}'))
cocoa_project_path = ed('cocoa/{}')
app = cocoa_app()
app_version = get_module_version('core')
cocoa_project_path = 'cocoa/se'
filereplace(op.join(cocoa_project_path, 'InfoTemplate.plist'), op.join('build', 'Info.plist'), version=app_version)
app.create(op.join('build', 'Info.plist'))
print("Building localizations")
build_localizations('cocoa', edition)
build_localizations('cocoa')
print("Building xibless UIs")
build_cocoalib_xibless()
build_xibless(edition)
build_xibless()
print("Building Python extensions")
build_cocoa_proxy_module()
build_cocoa_bridging_interfaces(edition)
build_cocoa_bridging_interfaces()
print("Building the cocoa layer")
copy_embeddable_python_dylib('build')
pydep_folder = op.join(app.resources, 'py')
if not op.exists(pydep_folder):
os.mkdir(pydep_folder)
shutil.copy(op.join(cocoa_project_path, 'dg_cocoa.py'), 'build')
specific_packages = {
'se': ['core_se'],
'me': ['core_me', 'hsaudiotag'],
'pe': ['core_pe'],
}[edition]
tocopy = [
'core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa', 'objp', 'send2trash'
] + specific_packages
'core', 'hscommon', 'cocoa/inter', 'cocoalib/cocoa', 'objp', 'send2trash', 'hsaudiotag',
]
copy_packages(tocopy, pydep_folder, create_links=dev)
sys.path.insert(0, 'build')
extra_deps = None
if edition == 'pe':
# ModuleFinder can't seem to correctly detect the multiprocessing dependency, so we have
# to manually specify it.
extra_deps = ['multiprocessing']
# ModuleFinder can't seem to correctly detect the multiprocessing dependency, so we have
# to manually specify it.
extra_deps = ['multiprocessing']
collect_stdlib_dependencies('build/dg_cocoa.py', pydep_folder, extra_deps=extra_deps)
del sys.path[0]
# Views are not referenced by python code, so they're not found by the collector.
@@ -156,12 +151,12 @@ def build_cocoa(edition, dev):
delete_files_with_pattern(pydep_folder, '__pycache__')
print("Compiling with WAF")
os.chdir('cocoa')
print_and_do('{0} waf configure --edition {1} && {0} waf'.format(sys.executable, edition))
print_and_do('{0} waf configure && {0} waf'.format(sys.executable))
os.chdir('..')
app.copy_executable('cocoa/build/dupeGuru')
build_help(edition)
build_help()
print("Copying resources and frameworks")
image_path = ed('cocoa/{}/dupeguru.icns')
image_path = 'cocoa/se/dupeguru.icns'
resources = [image_path, 'cocoa/base/dsa_pub.pem', 'build/dg_cocoa.py', 'build/help']
app.copy_resources(*resources, use_symlinks=dev)
app.copy_frameworks('build/Python', 'cocoalib/Sparkle.framework')
@@ -170,26 +165,26 @@ def build_cocoa(edition, dev):
run_contents = tmpl.replace('{{app_path}}', app.dest)
open('run.py', 'wt').write(run_contents)
def build_qt(edition, dev, conf):
def build_qt(dev):
print("Building localizations")
build_localizations('qt', edition)
build_localizations('qt')
print("Building Qt stuff")
print_and_do("pyrcc5 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py')))
fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py'))
build_help(edition)
print_and_do("pyrcc5 {0} > {1}".format(op.join('qt', 'dg.qrc'), op.join('qt', 'dg_rc.py')))
fix_qt_resource_file(op.join('qt', 'dg_rc.py'))
build_help()
print("Creating the run.py file")
filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition)
shutil.copy(op.join('qt', 'run_template.py'), 'run.py')
def build_help(edition):
def build_help():
print("Generating Help")
current_path = op.abspath('.')
help_basepath = op.join(current_path, 'help', 'en')
help_destpath = op.join(current_path, 'build', 'help'.format(edition))
changelog_path = op.join(current_path, 'help', 'changelog_{}'.format(edition))
help_destpath = op.join(current_path, 'build', 'help')
changelog_path = op.join(current_path, 'help', 'changelog_se')
tixurl = "https://github.com/hsoft/dupeguru/issues/{}"
appname = {'se': 'dupeGuru', 'me': 'dupeGuru Music Edition', 'pe': 'dupeGuru Picture Edition'}[edition]
homepage = 'http://www.hardcoded.net/dupeguru{}/'.format('_' + edition if edition != 'se' else '')
confrepl = {'edition': edition, 'appname': appname, 'homepage': homepage, 'language': 'en'}
appname = 'dupeGuru'
homepage = 'https://www.hardcoded.net/dupeguru/'
confrepl = {'appname': appname, 'homepage': homepage, 'language': 'en'}
changelogtmpl = op.join(current_path, 'help', 'changelog.tmpl')
conftmpl = op.join(current_path, 'help', 'conf.tmpl')
sphinxgen.gen(help_basepath, help_destpath, changelog_path, tixurl, confrepl, conftmpl, changelogtmpl)
@@ -198,10 +193,10 @@ def build_qt_localizations():
loc.compile_all_po(op.join('qtlib', 'locale'))
loc.merge_locale_dir(op.join('qtlib', 'locale'), 'locale')
def build_localizations(ui, edition):
def build_localizations(ui):
loc.compile_all_po('locale')
if ui == 'cocoa':
app = cocoa_app(edition)
app = cocoa_app()
loc.build_cocoa_localizations(app, en_stringsfile=op.join('cocoa', 'base', 'en.lproj', 'Localizable.strings'))
locale_dest = op.join(app.resources, 'locale')
elif ui == 'qt':
@@ -210,32 +205,19 @@ def build_localizations(ui, edition):
if op.exists(locale_dest):
shutil.rmtree(locale_dest)
shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot'))
if ui == 'qt' and not ISLINUX:
print("Copying qt_*.qm files into the 'locale' folder")
from PyQt5.QtCore import QLibraryInfo
trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
for lang in loc.get_langs('locale'):
qmname = 'qt_%s.qm' % lang
src = op.join(trfolder, qmname)
if op.exists(src):
copy(src, op.join('build', 'locale', qmname))
def build_updatepot():
if ISOSX:
print("Updating Cocoa strings file.")
# We need to have strings from *all* editions in here, so we'll call xibless for all editions
# in dummy subfolders.
build_cocoalib_xibless('cocoalib/autogen')
loc.generate_cocoa_strings_from_code('cocoalib', 'cocoalib/en.lproj')
for edition in ('se', 'me', 'pe'):
build_xibless(edition, op.join('cocoa', 'autogen', edition))
build_xibless('se', op.join('cocoa', 'autogen', 'se'))
loc.generate_cocoa_strings_from_code('cocoa', 'cocoa/base/en.lproj')
print("Building .pot files from source files")
print("Building core.pot")
all_cores = ['core', 'core_se', 'core_me', 'core_pe']
loc.generate_pot(all_cores, op.join('locale', 'core.pot'), ['tr'])
loc.generate_pot(['core'], op.join('locale', 'core.pot'), ['tr'])
print("Building columns.pot")
loc.generate_pot(all_cores, op.join('locale', 'columns.pot'), ['coltr'])
loc.generate_pot(['core'], op.join('locale', 'columns.pot'), ['coltr'])
print("Building ui.pot")
# When we're not under OS X, we don't want to overwrite ui.pot because it contains Cocoa locs
# We want to merge the generated pot with the old pot in the most preserving way possible.
@@ -279,7 +261,7 @@ def build_cocoa_proxy_module():
['cocoalib', 'cocoa/autogen']
)
def build_cocoa_bridging_interfaces(edition):
def build_cocoa_bridging_interfaces():
print("Building Cocoa Bridging Interfaces")
import objp.o2p
import objp.p2o
@@ -300,7 +282,7 @@ def build_cocoa_bridging_interfaces(edition):
from inter.result_table import PyResultTable, ResultTableView
from inter.stats_label import PyStatsLabel, StatsLabelView
from inter.app import PyDupeGuruBase, DupeGuruView
appmod = importlib.import_module('inter.app_{}'.format(edition))
appmod = importlib.import_module('inter.app_se')
allclasses = [
PyGUIObject, PyColumns, PyOutline, PySelectableList, PyTable, PyBaseApp,
PyDetailsPanel, PyDirectoryOutline, PyPrioritizeDialog, PyPrioritizeList, PyProblemDialog,
@@ -322,14 +304,21 @@ def build_cocoa_bridging_interfaces(edition):
def build_pe_modules(ui):
print("Building PE Modules")
exts = [
Extension("_block", [op.join('core_pe', 'modules', 'block.c'), op.join('core_pe', 'modules', 'common.c')]),
Extension("_cache", [op.join('core_pe', 'modules', 'cache.c'), op.join('core_pe', 'modules', 'common.c')]),
Extension(
"_block",
[op.join('core', 'pe', 'modules', 'block.c'), op.join('core', 'pe', 'modules', 'common.c')]
),
Extension(
"_cache",
[op.join('core', 'pe', 'modules', 'cache.c'), op.join('core', 'pe', 'modules', 'common.c')]
),
]
if ui == 'qt':
exts.append(Extension("_block_qt", [op.join('qt', 'pe', 'modules', 'block.c')]))
elif ui == 'cocoa':
exts.append(Extension(
"_block_osx", [op.join('core_pe', 'modules', 'block_osx.m'), op.join('core_pe', 'modules', 'common.c')],
"_block_osx",
[op.join('core', 'pe', 'modules', 'block_osx.m'), op.join('core', 'pe', 'modules', 'common.c')],
extra_link_args=[
"-framework", "CoreFoundation",
"-framework", "Foundation",
@@ -341,27 +330,25 @@ def build_pe_modules(ui):
ext_modules=exts,
)
move_all('_block_qt*', op.join('qt', 'pe'))
move_all('_block*', 'core_pe')
move_all('_cache*', 'core_pe')
move_all('_block*', op.join('core', 'pe'))
move_all('_cache*', op.join('core', 'pe'))
def build_normal(edition, ui, dev, conf):
print("Building dupeGuru {0} with UI {1}".format(edition.upper(), ui))
def build_normal(ui, dev):
print("Building dupeGuru with UI {}".format(ui))
add_to_pythonpath('.')
print("Building dupeGuru")
if edition == 'pe':
build_pe_modules(ui)
build_pe_modules(ui)
if ui == 'cocoa':
build_cocoa(edition, dev)
build_cocoa(dev)
elif ui == 'qt':
build_qt(edition, dev, conf)
build_qt(dev)
def main():
options = parse_args()
conf = json.load(open('conf.json'))
edition = conf['edition']
ui = conf['ui']
dev = conf['dev']
if dev:
ui = options.ui
if ui not in ('cocoa', 'qt'):
ui = 'cocoa' if ISOSX else 'qt'
if options.dev:
print("Building in Dev mode")
if options.clean:
for path in ['build', op.join('cocoa', 'build'), op.join('cocoa', 'autogen')]:
@@ -370,9 +357,9 @@ def main():
if not op.exists('build'):
os.mkdir('build')
if options.doc:
build_help(edition)
build_help()
elif options.loc:
build_localizations(ui, edition)
build_localizations(ui)
elif options.updatepot:
build_updatepot()
elif options.mergepot:
@@ -381,17 +368,17 @@ def main():
build_normpo()
elif options.cocoa_ext:
build_cocoa_proxy_module()
build_cocoa_bridging_interfaces(edition)
build_cocoa_bridging_interfaces()
elif options.cocoa_compile:
os.chdir('cocoa')
print_and_do('{0} waf configure --edition {1} && {0} waf'.format(sys.executable, edition))
print_and_do('{0} waf configure && {0} waf'.format(sys.executable))
os.chdir('..')
cocoa_app(edition).copy_executable('cocoa/build/dupeGuru')
cocoa_app().copy_executable('cocoa/build/dupeGuru')
elif options.xibless:
build_cocoalib_xibless()
build_xibless(edition)
build_xibless()
else:
build_normal(edition, ui, dev, conf)
build_normal(ui, options.dev)
if __name__ == '__main__':
main()