Skip to content

Commit b711377

Browse files
committed
makebuild
1 parent c9f5cf0 commit b711377

File tree

3 files changed

+147
-92
lines changed

3 files changed

+147
-92
lines changed

makebuild.py

Lines changed: 130 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,27 @@
1717
from PIL import Image
1818

1919

20-
path = os.environ['PATH']
21-
os.environ['PATH'] = ';'.join([path, os.path.join(path.split(';')[0], 'Scripts')])
20+
# path = os.environ['PATH']
21+
# os.environ['PATH'] = ';'.join([path, os.path.join(path.split(';')[0], 'Scripts')])
2222

2323

24-
class Build():
24+
class BuildBase():
2525

26-
@classmethod
27-
def run(self, run_installer=True):
28-
self.make_icon()
29-
self.set_version()
30-
self.set_appname()
31-
self.set_api_ms_win_crt_path()
32-
self.remove_build()
33-
self.make_build()
34-
# self.run_build()
35-
self.make_installer()
36-
self.compress_installer()
37-
if run_installer:
38-
self.run_installer()
39-
40-
@classmethod
41-
def make_icon(self):
42-
directory = os.path.join('assets', 'icon')
43-
src_path = os.path.join(directory, 'icon.png')
44-
dst_path = os.path.join(directory, 'icon.ico')
45-
icon_sizes = [(v, v) for v in (16, 24, 32, 48, 64, 96, 128, 256,)]
46-
img = Image.open(src_path)
47-
if os.path.exists(dst_path):
48-
os.remove(dst_path)
49-
img.save(dst_path, sizes=icon_sizes)
26+
class path():
27+
dist = 'dist'
28+
build = 'build'
29+
icondir = os.path.join('assets', 'icon')
30+
iconsrc = os.path.join(icondir, 'icon.png')
31+
icondst = os.path.join(icondir, 'icon.ico')
32+
mainsrc = os.path.join('source', 'main.py')
33+
spec = 'makebuild.spec'
34+
iss = 'makeinstaller.iss'
35+
winsxs = 'C:\\Windows\\WinSxS'
36+
issc = r'C:\\Program Files (x86)\\Inno Setup 5\\ISCC.exe'
5037

5138
@classmethod
5239
def remove_build(self):
53-
remove_paths = ['dist', 'build']
54-
for path in remove_paths:
40+
for path in [self.path.build, self.path.dist]:
5541
path = os.path.abspath(path)
5642
if os.path.isdir(path):
5743
try:
@@ -60,6 +46,14 @@ def remove_build(self):
6046
except Exception:
6147
print('removing failed %s' % (path))
6248

49+
@classmethod
50+
def make_icon(self):
51+
icon_sizes = [(v, v) for v in (16, 24, 32, 48, 64, 96, 128, 256,)]
52+
img = Image.open(self.path.iconsrc)
53+
if os.path.exists(self.path.icondst):
54+
os.remove(self.path.icondst)
55+
img.save(self.path.icondst, sizes=icon_sizes)
56+
6357
@classmethod
6458
def subfile(self, ptrn, repl, path, **kwargs):
6559
if not os.path.exists(path):
@@ -75,54 +69,23 @@ def subfile(self, ptrn, repl, path, **kwargs):
7569
return content
7670

7771
@classmethod
78-
def make_build(self):
79-
proc = subprocess.Popen('pyinstaller makebuild.spec', shell=True)
80-
proc.communicate()
81-
82-
@classmethod
83-
def get_appname(self):
84-
ptrn = (r'''[_]{0,2}appname[_]{0,2}[\s]{1,}[=]{1}[\s]{1,}'''
85-
r'''['"]{1}([a-zA-Z\s]{1,})['"]{1}''')
86-
with open(os.path.join('source', 'main.py'), 'r') as file:
87-
content = file.read()
88-
m = re.search(ptrn, content)
89-
if m:
90-
return m.group(1)
91-
92-
@classmethod
93-
def set_appname(self):
94-
ptrn = (r'''(__appname__[\s]{1,}=[\s]{1,}[\'\"]{1})'''
95-
r'''[\w\d\s\-\_\.]{0,}([\'\"]{1})''')
96-
appname = self.get_appname()
97-
if appname:
98-
self.subfile(ptrn, r'\g<1>{}\g<2>'.format(appname), 'makebuild.spec')
99-
100-
@classmethod
101-
def get_version(self):
102-
ptrn = (r'''[_]{0,2}version[_]{0,2}[\s]{1,}[=]{1}[\s]{1,}'''
103-
r'''['"]{1}([\d]{1,}\.[\d]{1,}\.[\d]{1,})['"]{1}''')
104-
with open(os.path.join('source', 'main.py'), 'r') as file:
72+
def get_info_from_source(self, key):
73+
ptrn = (r'''[_]{0,2}%s[_]{0,2}[\s]{1,}[=]{1}[\s]{1,}'''
74+
r'''['"]{1}([\w\d\.\-\s]{1,})['"]{1}''') % (key)
75+
with open(self.path.mainsrc, 'r') as file:
10576
content = file.read()
10677
m = re.search(ptrn, content)
10778
if m:
10879
return m.group(1)
10980

110-
@classmethod
111-
def set_version(self):
112-
ptrn = r'''([\d]{1,}\.[\d]{1,}\.[\d]{1,})'''
113-
version = self.get_version()
114-
if version:
115-
self.subfile(ptrn, version, 'makeinstaller.iss')
116-
11781
@classmethod
11882
def set_api_ms_win_crt_path(self, architecture='amd64'):
11983
# 'x86' or 'amd64'
12084
existing_dirs = []
121-
basedir = 'C:\\Windows\\WinSxS'
122-
for dirname in os.listdir(basedir):
85+
for dirname in os.listdir(self.path.winsxs):
12386
if not dirname.startswith(architecture):
12487
continue
125-
absdir = os.path.join(basedir, dirname)
88+
absdir = os.path.join(self.path.winsxs, dirname)
12689
if not os.path.isdir(absdir):
12790
continue
12891

@@ -135,59 +98,142 @@ def set_api_ms_win_crt_path(self, architecture='amd64'):
13598
ptrn = (r'''(__api_ms_win_crt_path__[\s]{1,}=[\s]{1,}[\'\"]{1})'''
13699
r'''[\w\d\s\-\_\.\:\\]{0,}([\'\"]{1})''')
137100
path = path.replace('\\', '\\\\\\\\')
138-
self.subfile(ptrn, r'\g<1>{}\g<2>'.format(path), 'makebuild.spec')
101+
self.subfile(ptrn, r'\g<1>{}\g<2>'.format(path), self.path.spec)
139102

140103
@classmethod
141-
def run_build(self):
142-
name = self.get_appname()
143-
command = '"{}"'.format(os.path.join('dist', '{}.exe'.format(name)))
104+
def make_build(self):
105+
command = 'pyinstaller {}'.format(self.path.spec)
144106
proc = subprocess.Popen(command, shell=True)
145107
proc.communicate()
146108

147109
@classmethod
148110
def make_installer(self):
149-
for name in os.listdir('dist'):
111+
for name in os.listdir(self.path.dist):
150112
if os.path.splitext(name)[0][-1].isdigit():
151-
os.remove(os.path.join('dist', name))
113+
os.remove(os.path.join(self.path.dist, name))
114+
command = '"{}" "{}"'.format(self.path.issc, self.path.iss)
115+
proc = subprocess.Popen(command, shell=True)
116+
proc.communicate()
152117

153-
issc = r'''"C:\\Program Files (x86)\\Inno Setup 5\\ISCC.exe"'''
154-
command = '''%s "makeinstaller.iss"''' % (issc)
118+
@classmethod
119+
def run_build(self):
120+
name = self.get_appname()
121+
command = '"{}"'.format(os.path.join(self.path.dist, '{}.exe'.format(name)))
155122
proc = subprocess.Popen(command, shell=True)
156123
proc.communicate()
157124

158125
@classmethod
159126
def get_installer_name(self):
160-
with open('makeinstaller.iss', 'r') as file:
127+
with open(self.path.iss, 'r') as file:
161128
for line in file.read().split('\n'):
162-
if line.startswith('OutputBaseFilename'):
163-
return line.split('=')[-1].strip()
129+
if 'OutputBaseFilename' in line:
130+
return line.split('=')[-1].strip('" ')
164131

165132
@classmethod
166133
def compress_installer(self):
167134
name = self.get_installer_name()
168135
if not name:
169136
return
170137
src_name = '{}.exe'.format(name)
171-
src_path = os.path.join('dist', src_name)
172-
dst_path = os.path.join('dist', '{}.zip'.format(name))
138+
src_path = os.path.join(self.path.dist, src_name)
139+
dst_path = os.path.join(self.path.dist, '{}.zip'.format(name))
173140
file = zipfile.ZipFile(dst_path, 'w', zipfile.ZIP_DEFLATED)
174141
file.write(src_path, src_name)
175-
# zipdir('tmp/', zipf)
176142
file.close()
177-
# for root, dirs, files in os.walk(path):
178-
# for file in files:
179-
# ziph.write(os.path.join(root, file))
180143

181144
@classmethod
182145
def run_installer(self):
183146
name = self.get_installer_name()
184147
if not name:
185148
return
186-
command = '"{}"'.format(os.path.join('dist', name))
149+
command = '"{}"'.format(os.path.join(self.path.dist, name))
187150
proc = subprocess.Popen(command, shell=True)
188151
proc.communicate()
189152

190153

154+
class Build(BuildBase):
155+
156+
@classmethod
157+
def run(self, auto_build_info=True, run_installer=True):
158+
159+
self.make_icon()
160+
161+
if auto_build_info:
162+
163+
self.set_dist()
164+
self.set_author()
165+
self.set_appname()
166+
self.set_version()
167+
168+
self.set_api_ms_win_crt_path()
169+
self.remove_build()
170+
self.make_build()
171+
# self.run_build()
172+
self.make_installer()
173+
self.compress_installer()
174+
175+
if run_installer:
176+
self.run_installer()
177+
178+
@classmethod
179+
def get_appname(self):
180+
return self.get_info_from_source('appname')
181+
182+
@classmethod
183+
def get_version(self):
184+
return self.get_info_from_source('version')
185+
186+
@classmethod
187+
def get_author(self):
188+
return self.get_info_from_source('author')
189+
190+
@classmethod
191+
def set_appname(self):
192+
appname = self.get_appname()
193+
if appname:
194+
ptrn = (r'''(__appname__[\s]{1,}=[\s]{1,}[\'\"]{1})'''
195+
r'''[\w\d\s\-\_\.]{0,}([\'\"]{1})''')
196+
self.subfile(ptrn, r'\g<1>{}\g<2>'.format(appname), self.path.spec)
197+
198+
keys = r'|'.join([
199+
'AppName', 'AppVerName',
200+
'DefaultDirName', 'DefaultGroupName',
201+
'UninstallDisplayIcon', 'OutputBaseFilename', 'Name', 'Filename'])
202+
version_ptrn = r'[\d]{1,}\.[\d]{1,}\.[\d]{1,}'
203+
ptrn = (r'(%s)'
204+
r'([\s]{1,}[\=\:]{1}[\s]{1,}\")'
205+
r'(\{[a-z]{1,}\}\\){0,1}'
206+
r'[\w\d\s]{1,}'
207+
r'(|\.exe|[\s\-\_\.]{1}%s[\s\-\_\.]{0,}[\w\d]{0,})'
208+
r'(\")') % (keys, version_ptrn)
209+
self.subfile(ptrn, r'\g<1>\g<2>\g<3>{}\g<4>\g<5>'.format(appname), self.path.iss)
210+
211+
@classmethod
212+
def set_version(self):
213+
version = self.get_version()
214+
if version:
215+
ptrn = r'([\d]{1,}\.[\d]{1,}\.[\d]{1,})'
216+
self.subfile(ptrn, version, self.path.iss)
217+
218+
@classmethod
219+
def set_author(self):
220+
author = self.get_author()
221+
if author:
222+
keys = r'|'.join([
223+
'AppCopyright', 'AppPublisher',
224+
'VersionInfoCompany', 'VersionInfoCopyright'])
225+
ptrn = r'(%s)([\s]{1,}=[\s]{1,}\")[\w\d\s\.\-\_]{1,}(\")' % (keys)
226+
self.subfile(ptrn, r'\g<1>\g<2>{}\g<3>'.format(author), self.path.iss)
227+
228+
@classmethod
229+
def set_dist(self):
230+
ptrn = (r'(Source|OutputDir)'
231+
r'([\s]{0,}\:[\s]{0,}\")'
232+
r'[\w\d\s\.\-\_]{1,}'
233+
r'(\\\*){0,}'
234+
r'(\")')
235+
self.subfile(ptrn, r'\g<1>\g<2>{}\g<3>\g<4>'.format(self.path.dist), self.path.iss)
236+
191237
if __name__ == '__main__':
192238
from io import TextIOWrapper
193239
sys.stdout = TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')

makeinstaller.iss

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1+
; http://www.jrsoftware.org/ishelp/index.php
2+
13
[Setup]
2-
AppName=PyWinLayout
3-
AppVerName=PyWinLayout 0.1.0
4-
DefaultDirName={pf}\PyWinLayout
5-
DefaultGroupName=PyWinLayout
6-
AppPublisher=Taehong Kim
7-
UninstallDisplayIcon={app}\PyWinLayout.exe
4+
AppName="PyWinLayout"
5+
AppVerName="PyWinLayout 0.1.1"
6+
DefaultDirName="{pf}\PyWinLayout"
7+
DefaultGroupName="PyWinLayout"
8+
AppVersion="0.1.1"
9+
AppCopyright="Taehong Kim"
10+
AppPublisher="Taehong Kim"
11+
UninstallDisplayIcon="{app}\PyWinLayout.exe"
812
Compression=lzma2/max
913
SolidCompression=yes
1014
OutputDir="dist"
11-
OutputBaseFilename=PyWinLayout-0.1.0-Setup
15+
OutputBaseFilename="PyWinLayout-0.1.1-Setup"
16+
; VersionInfoVersion="0.1.1"
17+
VersionInfoProductVersion="0.1.1"
18+
VersionInfoCompany="Taehong Kim"
19+
VersionInfoCopyright="Taehong Kim"
20+
ArchitecturesInstallIn64BitMode="x64"
1221

1322
[Files]
1423
Source: "dist\*"; DestDir: "{app}"; Flags: recursesubdirs

source/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
__appname__ = 'PyWinLayout'
5-
__version__ = '0.1.0'
5+
__version__ = '0.1.1'
66
__author__ = 'Taehong Kim'
77
__email__ = '[email protected]'
88
__license__ = ''

0 commit comments

Comments
 (0)