Skip to content

Commit 9a5d387

Browse files
committed
support not creating a base package
This is implemented by making PROVIDES optional and making the recipe not declare anything to provide. PROVIDES de facto defines (sub)packages, so leaving it out should be natural for a package that isn't actually created. A build package (with fake PROVIDES) is still created to have a writable $prefix. A policy check is added that the main packaging directory is empty after INSTALL() and that the recipe still at least declares one actual package. Fixes #192.
1 parent 983ad55 commit 9a5d387

5 files changed

Lines changed: 45 additions & 16 deletions

File tree

HaikuPorter/BuildMaster.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ def __init__(self, port, portsTreePath, missingPackageIDs,
5050
self.recipeFilePath \
5151
= os.path.relpath(port.recipeFilePath, portsTreePath)
5252
self.resultingPackages \
53-
= [package.hpkgName for package in self.port.packages]
53+
= [package.hpkgName for package in self.port.packages
54+
if not package.isFakeEmptyPackage()]
5455
self.packageRepository = packageRepository
5556
self.requiredPackages = presentDependencyPackages
5657
self.requiredPackageIDs = [
@@ -100,7 +101,8 @@ def __init__(self, portsTreePath, port, reason):
100101
self.recipeFilePath \
101102
= os.path.relpath(port.recipeFilePath, portsTreePath)
102103
self.resultingPackages \
103-
= [package.hpkgName for package in port.packages]
104+
= [package.hpkgName for package in port.packages
105+
if not package.isFakeEmptyPackage()]
104106
else:
105107
self.port = None
106108
self.name = port
@@ -325,7 +327,8 @@ def runBuilds(self):
325327
# Move anything to the lost state that depends on skipped builds.
326328
for skippedBuild in self.skippedBuilds:
327329
if skippedBuild.port:
328-
self._packagesCompleted(skippedBuild.port.packages, False)
330+
self._packagesCompleted([package for package in skippedBuild.port.packages
331+
if not package.isFakeEmptyPackage()], False)
329332

330333
try:
331334
self._ensureConsistentSchedule()
@@ -451,7 +454,8 @@ def _packagesCompleted(self, packages, available):
451454
else:
452455
# the build was lost, propagate lost packages
453456
self.lostBuilds.append(blockedBuild)
454-
completePackages += blockedBuild.port.packages
457+
completePackages += [package for package in blockedBuild.port.packages
458+
if not package.isFakeEmptyPackage()]
455459
else:
456460
stillBlockedBuilds.append(blockedBuild)
457461

@@ -466,7 +470,8 @@ def _buildComplete(self, scheduledBuild, buildSuccess, listToUse):
466470
self.activeBuilds.remove(scheduledBuild)
467471
listToUse.append(scheduledBuild)
468472

469-
self._packagesCompleted(scheduledBuild.port.packages, buildSuccess)
473+
self._packagesCompleted([package for package in scheduledBuild.port.packages
474+
if not package.isFakeEmptyPackage()], buildSuccess)
470475

471476
def _buildThread(self, builder, scheduledBuild, buildNumber):
472477
self.logger.info('starting build ' + str(buildNumber) + ', '

HaikuPorter/Package.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,17 @@ def adjustToChroot(self):
207207
def populatePackagingDir(self, port):
208208
"""Prefill packaging directory with stuff from the outside"""
209209

210+
if self.isFakeEmptyPackage():
211+
# don't add files to a fake package
212+
return
213+
210214
licenseDir = port.baseDir + '/licenses'
211215
if os.path.exists(licenseDir):
212216
shutil.copytree(licenseDir, self.packagingDir + '/data/licenses')
213217

218+
def isFakeEmptyPackage(self):
219+
return 'PROVIDES' not in self.recipeKeys or len(self.recipeKeys['PROVIDES']) == 0
220+
214221
def makeHpkg(self, requiresUpdater):
215222
"""Create a package suitable for distribution"""
216223

@@ -221,6 +228,10 @@ def makeHpkg(self, requiresUpdater):
221228
# policy check, add some requires
222229
self.policy.checkPackage(self, packageFile)
223230

231+
if self.isFakeEmptyPackage():
232+
# don't actually create the package
233+
return
234+
224235
if (requiresUpdater and self.type != PackageType.SOURCE):
225236
requiresList = self.recipeKeys['REQUIRES']
226237
self.recipeKeys['UPDATED_REQUIRES'] \
@@ -270,7 +281,7 @@ def createBuildPackage(self):
270281
buildPackageInfo = (self.buildPackageDir + '/' + self.revisionedName
271282
+ '-build.PackageInfo')
272283
self._generatePackageInfo(buildPackageInfo,
273-
['REQUIRES', 'BUILD_REQUIRES', 'BUILD_PREREQUIRES'], True, False,
284+
['REQUIRES', 'BUILD_REQUIRES', 'BUILD_PREREQUIRES'], True, self.isFakeEmptyPackage(),
274285
False, self.architecture)
275286

276287
# create the build package
@@ -322,10 +333,7 @@ def _generatePackageInfo(self, packageInfoPath, requiresToUse, quiet,
322333
os.remove(packageInfoPath)
323334

324335
with codecs.open(packageInfoPath, 'w', 'utf-8') as infoFile:
325-
if fakeEmptyProvides:
326-
infoFile.write('name\t\t\tfaked_' + self.name + '\n')
327-
else:
328-
infoFile.write('name\t\t\t' + self.name + '\n')
336+
infoFile.write('name\t\t\t' + self.name + '\n')
329337
infoFile.write('version\t\t\t' + self.fullVersion + '\n')
330338
infoFile.write('architecture\t\t' + architecture + '\n')
331339
infoFile.write('summary\t\t\t"'
@@ -375,7 +383,7 @@ def _generatePackageInfo(self, packageInfoPath, requiresToUse, quiet,
375383
requires.append(require)
376384

377385
if fakeEmptyProvides:
378-
infoFile.write('provides {\n\tfaked_' + self.name + ' = '
386+
infoFile.write('provides {\n\t' + self.name + ' = '
379387
+ self.version + '\n}\n')
380388
else:
381389
self._writePackageInfoListByKey(infoFile, 'PROVIDES',

HaikuPorter/Policy.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ def checkPackage(self, package, packageFile):
7676
self.provides = self._parseResolvableExpressionListForKey('PROVIDES')
7777
self.requires = self._parseResolvableExpressionListForKey('REQUIRES')
7878

79+
if package.isFakeEmptyPackage():
80+
self._checkFakePackageIsEmpty()
7981
self._checkTopLevelEntries()
80-
self._checkProvides()
82+
if not package.isFakeEmptyPackage():
83+
self._checkProvides()
8184
self._checkLibraryDependencies()
8285
self._checkMisplacedDevelopLibraries()
8386
self._checkGlobalWritableFiles()
@@ -88,6 +91,10 @@ def checkPackage(self, package, packageFile):
8891
if self.strict and self.violationEncountered:
8992
sysExit("packaging policy violation(s) in strict mode")
9093

94+
def _checkFakePackageIsEmpty(self):
95+
if len(os.listdir(self.package.packagingDir)) > 0:
96+
self._violation("package without PROVIDES isn't empty")
97+
9198
def _checkTopLevelEntries(self):
9299
for entry in os.listdir(self.package.packagingDir):
93100
if entry not in allowedTopLevelEntries:

HaikuPorter/Port.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ def validateRecipeFile(self, showWarnings=False):
283283
entries = recipeConfig.getEntriesForExtension(extension)
284284
recipeKeys = {}
285285

286+
# make PROVIDES required for subpackages
287+
if extension:
288+
recipeAttributes['PROVIDES']['required'] = True
289+
286290
# check whether all required values are present
287291
for baseKey in recipeAttributes.keys():
288292
if extension:
@@ -516,8 +520,9 @@ def removeDependencyInfosFromRepository(self):
516520
@property
517521
def mainPackage(self):
518522
self.parseRecipeFileIfNeeded()
519-
if self.packages:
520-
return self.packages[0]
523+
for package in self.packages:
524+
if not package.isFakeEmptyPackage():
525+
return package
521526
return None
522527

523528
@property
@@ -1037,6 +1042,10 @@ def _parseRecipeFile(self, showWarnings, forceAllowUnstable=False):
10371042
forceAllowUnstable):
10381043
self.packages.append(package)
10391044

1045+
# check that we have any actual package
1046+
if not any(not package.isFakeEmptyPackage() for package in self.allPackages):
1047+
sysExit("recipe '%s' doesn't define any package" % self.recipeFilePath)
1048+
10401049
if not self.isMetaPort:
10411050
# create source package if it hasn't been specified or disabled:
10421051
if (not haveSourcePackage and not keys['DISABLE_SOURCE_PACKAGE']

HaikuPorter/RecipeAttributes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ def getRecipeFormatVersion():
221221
},
222222
'PROVIDES': {
223223
'type': ProvidesList,
224-
'required': True,
225-
'default': None,
224+
'required': False,
225+
'default': [],
226226
'extendable': Extendable.DEFAULT,
227227
'indexable': False,
228228
},

0 commit comments

Comments
 (0)