2 # -*- coding: utf-8 -*-
4 # Hardlink only packages used in the build from one directory to another,
5 # and updates the RemotePackageRepository file at the same time.
7 # Copyright 2017 Augustin Cavalier <waddlesplash>
8 # Distributed under the terms of the MIT License.
10 import sys
, os
, re
, hashlib
13 print("usage: hardlink_packages.py [arch] [jam RemotePackageRepository file] "
14 + "[prebuilt packages directory] [destination root directory]")
15 print("note that the [jam RemotePackageRepository file] will be modified.")
16 print("note that [target directory] is assumed to have a 'packages' subdirectory, "
17 + " and a repo.info.template file (using $ARCH$)")
20 args_arch
= sys
.argv
[1]
21 args_jamf
= sys
.argv
[2]
22 args_src
= sys
.argv
[3]
23 args_dst
= sys
.argv
[4]
25 if not args_dst
.endswith('/'):
26 args_dst
= args_dst
+ '/'
27 if not args_src
.endswith('/'):
28 args_src
= args_src
+ '/'
30 args_dst_packages
= args_dst
+ 'packages/'
33 for filename
in os
.listdir(args_src
):
34 if (not (filename
.endswith("-" + args_arch
+ ".hpkg")) and
35 not (filename
.endswith("-any.hpkg"))):
37 packageVersions
.append(filename
)
39 # Read RemotePackageRepository file and hardlink relevant packages
40 pattern
= re
.compile("^[a-z0-9]")
44 with
open(args_jamf
) as f
:
49 if not (pattern
.match(pkg
)):
50 # not a package (probably a Jam directive)
51 newFileForJam
.append(line
)
55 pkgname
= pkg
[:pkg
.index('-')]
58 if (len(pkgname
) == 0):
59 # no version, likely a source/debuginfo listing
60 newFileForJam
.append(line
)
63 greatestVersion
= None
64 for pkgVersion
in packageVersions
:
65 if (pkgVersion
.startswith(pkgname
+ '-') and
66 ((greatestVersion
== None) or (pkgVersion
> greatestVersion
))):
67 greatestVersion
= pkgVersion
68 if (greatestVersion
== None):
69 print("not found: " + pkg
)
70 newFileForJam
.append(line
)
74 # found it, so hardlink it
75 if not (os
.path
.exists(args_dst_packages
+ greatestVersion
)):
76 os
.link(args_src
+ greatestVersion
, args_dst_packages
+ greatestVersion
)
77 if ('packages/' + greatestVersion
) not in packageFiles
:
78 packageFiles
.append('packages/' + greatestVersion
)
79 # also hardlink the source package, if one exists
80 srcpkg
= greatestVersion
.replace("-" + args_arch
+ ".hpkg",
81 "-source.hpkg").replace('-', '_source-', 1)
82 if os
.path
.exists(args_src
+ srcpkg
):
83 if not os
.path
.exists(args_dst_packages
+ srcpkg
):
84 os
.link(args_src
+ srcpkg
, args_dst_packages
+ srcpkg
)
85 if ('packages/' + srcpkg
) not in packageFiles
:
86 packageFiles
.append('packages/' + srcpkg
)
87 newFileForJam
.append("\t" + greatestVersion
[:greatestVersion
.rfind('-')] + "\n");
92 finalizedNewFile
= "".join(newFileForJam
).encode('UTF-8')
93 with
open(args_jamf
, 'wb') as f
:
94 f
.write(finalizedNewFile
)
96 listhash
= hashlib
.sha256(finalizedNewFile
).hexdigest()
98 os
.mkdir(args_dst
+ listhash
)
100 print("dir " + listhash
+ " already exists. No changes?")
103 repodir
= args_dst
+ listhash
+ '/'
104 os
.symlink('../packages', repodir
+ 'packages')
106 with
open(args_dst
+ 'repo.info.template', 'r') as ritf
:
107 repoInfoTemplate
= ritf
.read()
109 repoInfoTemplate
= repoInfoTemplate
.replace("$ARCH$", args_arch
)
110 with
open(repodir
+ 'repo.info', 'w') as rinf
:
111 rinf
.write(repoInfoTemplate
)
114 with
open(repodir
+ 'package.list', 'w') as pkgl
:
115 pkgl
.write("\n".join(packageFiles
))
117 if os
.system('cd ' + repodir
+ ' && package_repo create repo.info ' + " ".join(packageFiles
)) != 0:
118 print("failed to create package repo.")
121 if os
.system('cd ' + repodir
+ ' && sha256sum repo >repo.sha256') != 0:
122 print("failed to checksum package repo.")