1# -*- coding: utf-8 -*- 2# 3# Copyright 2007-2011 Brecht Machiels 4# Copyright 2009-2010 Chris Roberts 5# Copyright 2009-2011 Scott McCreary 6# Copyright 2009 Alexander Deynichenko 7# Copyright 2009 HaikuBot (aka RISC) 8# Copyright 2010-2011 Jack Laxson (Jrabbit) 9# Copyright 2011 Ingo Weinhold 10# Copyright 2013 Oliver Tappe 11# Copyright 2016 Jerome Duval 12# Distributed under the terms of the MIT License. 13 14# -- Modules ------------------------------------------------------------------ 15 16from multiprocessing import cpu_count 17from optparse import OptionGroup, OptionParser 18 19from .__version__ import __version__ 20from .Utils import isCommandAvailable, warn 21 22# -- global options ----------------------------------------------------------- 23 24global __Options__ 25 26 27# -- getOption ===------------------------------------------------------------- 28 29def getOption(string): 30 """Fetches an option by name""" 31 32 return getattr(__Options__, string) 33 34 35# -- splitCommaSeparatedList -------------------------------------------------- 36 37def setCommaSeparatedList(option, opt, value, parser): 38 setattr(parser.values, option.dest, value.split(',')) 39 40 41# -- parseOptions ------------------------------------------------------------- 42 43def parseOptions(): 44 """Does command line argument parsing""" 45 46 parser = OptionParser( 47 usage='usage: %prog [options] portname[-portversion]', 48 version='%prog ' + __version__) 49 50 basic_actions = OptionGroup(parser, "Basic Actions", "Basic haikuporter actions") 51 52 basic_actions.add_option('-l', '--list', 53 action='store_true', dest='list', default=False, 54 help='list available ports') 55 basic_actions.add_option('--list-packages', 56 action='store_true', dest='listPackages', default=False, 57 help='list available packages') 58 basic_actions.add_option('-a', '--about', 59 action='store_true', dest='about', default=False, 60 help='show description of the specified port') 61 62 basic_actions.add_option('-s', '--search', 63 action='store_true', dest='search', default=False, 64 help='search for a port (regex)') 65 basic_actions.add_option('--search-packages', 66 action='store_true', dest='searchPackages', default=False, 67 help='search for a package (regex)') 68 basic_actions.add_option('-E', '--enter-chroot', 69 action='store_true', dest='enterChroot', default=False, 70 help="just enter the chroot()-environment, do not build") 71 basic_actions.add_option('--do-bootstrap', 72 action='store_true', dest='doBootstrap', default=False, 73 help="build all packages with cyclic dependencies") 74 basic_actions.add_option('-D', '--analyze-dependencies', 75 action='store_true', dest='analyzeDependencies', 76 default=False, 77 help="analyze dependencies between ports and print " 78 "information; no port parameter required") 79 basic_actions.add_option('-c', '--clean', 80 action='store_true', dest='clean', default=False, 81 help="clean the working directory of the specified port") 82 83 basic_actions.add_option('--purge', 84 action='store_true', dest='purge', default=False, 85 help="clean the working directory and remove downloads " 86 "of the specified port") 87 basic_actions.add_option('-g', '--get', 88 action='store_true', dest='get', default=False, 89 help="get/update the ports tree") 90 basic_actions.add_option('-t', '--tree', 91 action='store_true', dest='tree', default=False, 92 help="print out the location of the haikuports source " 93 "tree") 94 basic_actions.add_option('--lint', 95 action='store_true', dest='lint', default=False, 96 help="scan the ports tree for problems") 97 basic_actions.add_option('--list-dependencies', action='store_true', 98 dest='listDependencies', default=False, 99 help='list dependencies of a port') 100 basic_actions.add_option('--build-master', action='store_true', dest='buildMaster', 101 default=False, 102 help='run as build master and delegate builds to builders') 103 104 105 basic_flags = OptionGroup(parser, "Basic Options", "Basic modifications to haikuporter functionality") 106 107 basic_flags.add_option('-o', '--location', 108 action='store_true', dest='location', default=False, 109 help="print out the location of a recipe (via search, " 110 "for scripted editing)") 111 112 basic_flags.add_option('-q', '--quiet', 113 action='store_true', dest='quiet', default=False, 114 help="suppress output from build actions") 115 basic_flags.add_option('-v', '--verbose', 116 action='store_true', dest='verbose', default=False, 117 help="show why the recipe is broken") 118 basic_flags.add_option('-y', '--yes', 119 action='store_true', dest='yes', default=False, 120 help="answer yes to all questions") 121 basic_flags.add_option('-j', '--jobs', 122 action='store', type="int", dest='jobs', default=cpu_count(), 123 help="the number of concurrent jobs to build with") 124 basic_flags.add_option('-S', '--strict-policy', 125 action='store_true', dest='strictPolicy', default=False, 126 help="require strict packaging policy adherence; " 127 "packaging will fail on any policy violation") 128 basic_flags.add_option('--debug', 129 action='store_true', dest='debug', default=False, 130 help="show Python stack traces for fatal errors") 131 132 basic_flags.add_option('-n', '--nopatch', 133 action='store_false', dest='patch', default=True, 134 help="don't patch the sources, just download and unpack") 135 basic_flags.add_option('-e', '--extract-patchset', 136 action='store_true', dest='extractPatchset', default=False, 137 help='extract current patchset(s) from port source(s)') 138 basic_flags.add_option('-G', '--no-git-repo', 139 action='store_true', dest='noGitRepo', default=False, 140 help="don't create git-repo(s) for port source(s)") 141 basic_flags.add_option('-B', '--patch-files-only', 142 action='store_true', dest='patchFilesOnly', 143 default=False, 144 help="don't build the port, just download, unpack and " 145 "apply patch files; don't call PATCH() though") 146 basic_flags.add_option('-b', '--nobuild', 147 action='store_false', dest='build', default=True, 148 help="don't build the port, just download, unpack and " 149 "patch") 150 basic_flags.add_option('-p', '--nopackage', 151 action='store_false', dest='package', default=True, 152 help="don't create package, stop after build") 153 basic_flags.add_option('--all-dependencies', 154 action='store_true', dest='allDependencies', default=False, 155 help="build all outdated dependencies for the given port.") 156 basic_flags.add_option('--get-dependencies', 157 action='store_true', dest='getDependencies', default=False, 158 help="install all needed dependencies, then build the port") 159 basic_flags.add_option('--update-dependencies', 160 action='store_true', dest='updateDependencies', default=False, 161 help="build or update required dependencies (stop on hpkg)," 162 " then build the port") 163 basic_flags.add_option('--missing-dependencies', action='store_true', 164 dest='missingDependencies', default=False, help='build missing direct' 165 ' and indirect dependencies, then build the port') 166 167 basic_flags.add_option('--no-source-packages', 168 action='store_true', dest='noSourcePackages', 169 default=False, 170 help="don't create any source packages") 171 basic_flags.add_option('--test', 172 action='store_true', dest='test', default=False, 173 help="run tests on resulting binaries") 174 basic_flags.add_option('-C', '--nochroot', 175 action='store_false', dest='chroot', default=True, 176 help="build without a chroot()-environment - meant " 177 "for debugging the build/install process") 178 basic_flags.add_option('-f', '--force', 179 action='store_true', dest='force', default=False, 180 help="force to perform the steps (unpack, patch, build)") 181 basic_flags.add_option('-F', '--preserve-flags', 182 action='store_true', dest='preserveFlags', default=False, 183 help="don't clear any flags when a changed recipe file " 184 "is detected") 185 186 basic_flags.add_option('-P', '--portsfile', 187 action='store', type='string', dest='portsfile', 188 default='', 189 help="handle all ports in the given file") 190 basic_flags.add_option('--create-source-packages', 191 action='store_true', 192 dest='createSourcePackages', 193 default=False, 194 help="build only the (regular) source packages") 195 basic_flags.add_option('--create-source-packages-for-bootstrap', 196 action='store_true', 197 dest='createSourcePackagesForBootstrap', 198 default=False, 199 help="build only source packages as required by the" 200 "bootstrap image") 201 basic_flags.add_option('-w', '--why', 202 action='store', type='string', dest='why', 203 default='', 204 help='determine why the given port is pulled in as a ' 205 'dependency of the port to be built') 206 207 basic_flags.add_option('--config', 208 action='store', type='string', dest='configFile', 209 default=None, 210 help='specifies the location of the global config file; ' 211 'the default is "~/config/settings/haikuports.conf"') 212 213 basic_flags.add_option('--print-raw', action='store_true', dest='printRaw', 214 default=False, help='print machine readable output for use by scripts') 215 216 basic_flags.add_option('--print-filenames', action='store_true', 217 dest='printFilenames', default=False, help='print filenames instead of ' 218 + 'package names in package listings and searches') 219 220 basic_flags.add_option('--ignore-messages', action='store_true', 221 dest='ignoreMessages', default=False, 222 help='ignore messages within recipes') 223 224 advanced_flags = OptionGroup(parser, "Advanced Options", "Advanced modifications to haikuporter functionality") 225 226 advanced_flags.add_option('--cross-devel-package', 227 action='store', type='string', dest='crossDevelPackage', 228 default=None, 229 help='path to the cross development package (the actual ' 230 '"sysroot" package); the default (when ' 231 'cross-building at all) is the one to be found in ' 232 '"/boot/system/develop/cross" matching the target ' 233 'architecture') 234 advanced_flags.add_option('--secondary-cross-devel-packages', 235 action='callback', callback=setCommaSeparatedList, 236 type='string', dest='secondaryCrossDevelPackages', 237 default=[], 238 help='comma-separated list of paths to a secondary cross ' 239 'development package (the actual "sysroot" ' 240 'package); one path must be specified for each ' 241 'configured secondary target architecture ' 242 '(specified in the same order)') 243 advanced_flags.add_option('--licenses', 244 action='store', type='string', dest='licensesDirectory', 245 default=None, 246 help='path to the directory containing the well-known ' 247 'licenses; the default is ' 248 '"<systemDir>/data/licenses"') 249 advanced_flags.add_option('--system-mimedb', 250 action='store', type='string', dest='systemMimeDB', 251 default=None, 252 help='path to the directory containing the system ' 253 'MIME DB; the default is "<systemDir>/data/mime_db"') 254 advanced_flags.add_option('--command-mimeset', 255 action='store', type='string', dest='commandMimeset', 256 default=None, 257 help='specifies the "mimeset" command; ' 258 'the default is "mimeset"') 259 advanced_flags.add_option('--command-package', 260 action='store', type='string', dest='commandPackage', 261 default=None, 262 help='specifies the "package" command; ' 263 'the default is "package"') 264 advanced_flags.add_option('--command-package-repo', 265 action='store', type='string', dest='commandPackageRepo', 266 default=None, 267 help='specifies the "package_repo" command; ' 268 'the default is "package_repo"') 269 advanced_flags.add_option('--cross-tools', 270 action='store', type='string', dest='crossTools', 271 default=None, 272 help='specifies the path to the cross-tools directory ' 273 'created by the Haiku build system\'s configure ' 274 'script') 275 276 advanced_flags.add_option('--sourceforge-mirror', 277 action='store', type='string', dest='sourceforgeMirror', 278 default=None, 279 help='mirror to be used for sourceforge') 280 advanced_flags.add_option('--no-system-packages', action='store_true', 281 dest='noSystemPackages', default=False, 282 help='do not use system packages to resolve dependencies') 283 284 advanced_flags.add_option('--repository-update', action='store_true', 285 dest='repositoryUpdate', default=False, 286 help='update dependency infos in the repository') 287 advanced_flags.add_option('--check-repository-consistency', action='store_true', 288 dest='checkRepositoryConsistency', default=False, 289 help='check the consistency of the repository') 290 advanced_flags.add_option('--no-repository-update', action='store_true', 291 dest='noRepositoryUpdate', default=False, 292 help='do not update dependency infos in the repository') 293 advanced_flags.add_option('--no-package-obsoletion', action='store_true', 294 dest='noPackageObsoletion', default=False, 295 help='do not move obsolete packages out of packages dir') 296 advanced_flags.add_option('--prune-package-repository', action='store_true', 297 dest='prunePackageRepository', default=False, 298 help='prune the package repository') 299 advanced_flags.add_option('--create-package-repository', action='store', 300 type='string', dest='createPackageRepository', default=None, 301 help='create a package repository at the given output path') 302 advanced_flags.add_option('--sign-package-repository-privkey-file', action='store', 303 type='string', dest='packageRepositorySignPrivateKeyFile', default=None, 304 help='sign the package repository with the given minisign private key file') 305 advanced_flags.add_option('--sign-package-repository-privkey-pass', action='store', 306 type='string', dest='packageRepositorySignPrivateKeyPass', default=None, 307 help='sign the package repository with the given minisign password') 308 advanced_flags.add_option('--check-package-repository-consistency', 309 action='store_true', dest='checkPackageRepositoryConsistency', 310 default=False, help='check consistency of package repository by' 311 + ' dependency solving all packages') 312 advanced_flags.add_option('--literal-search-strings', action='store_true', 313 dest='literalSearchStrings', default=False, 314 help='treat search strings as literals instead of as expressions') 315 advanced_flags.add_option('--ports-for-files', action='store_true', 316 dest='portsForFiles', default=False, 317 help='list all ports affected by the supplied list of files') 318 advanced_flags.add_option('--ports-for-packages', action='store_true', 319 dest='portsForPackages', default=False, 320 help='list ports producing the supplied list of packages') 321 advanced_flags.add_option('--active-versions-only', action='store_true', 322 dest='activeVersionsOnly', default=False, 323 help='only check in active versions of ports instead of all ports') 324 advanced_flags.add_option('--check-ports-releases', action='store_true', 325 dest='checkPortsReleases', default=False, 326 help='check for newer releases of ports published upstream') 327 328 buildmaster_flags = OptionGroup(parser, "Build Master Options", 329 "Options only relevant to Haikuporter running in build master mode") 330 buildmaster_flags.add_option('--system-packages-directory', action='store', 331 type='string', dest='systemPackagesDirectory', default=None, 332 help='specifies the directory to be used to look up system packages') 333 buildmaster_flags.add_option('--build-master-output-dir', action='store', 334 type='string', dest='buildMasterOutputDir', default=None, 335 help='specifies where build master output shall be written') 336 buildmaster_flags.add_option('--reporting-uri', action='store', type='string', 337 dest='reportingURI', default=None, 338 help='specifies an optional remote reporting server (ex: mongodb://)') 339 buildmaster_flags.add_option('--local-builders', action='store', type='int', 340 dest='localBuilders', default=0, help='number of local builders (native Haiku only)') 341 buildmaster_flags.add_option('--console', action='store_true', dest='display', 342 default=False, 343 help='display a build master curses console') 344 345 parser.add_option_group(basic_actions) 346 parser.add_option_group(basic_flags) 347 parser.add_option_group(advanced_flags) 348 parser.add_option_group(buildmaster_flags) 349 350 global __Options__ 351 352 (__Options__, args) = parser.parse_args() 353 354 # some normalization 355 if (getOption('patchFilesOnly') or not getOption('patch') 356 or getOption('extractPatchset')): 357 setattr(__Options__, 'build', False) 358 if not getOption('build'): 359 setattr(__Options__, 'package', False) 360 if getOption('updateDependencies') or getOption('missingDependencies'): 361 setattr(__Options__, 'allDependencies', True) 362 if getOption('enterChroot'): 363 setattr(__Options__, 'noSourcePackages', True) 364 elif not isCommandAvailable('git'): 365 if not getOption('doBootstrap'): 366 warn("deactivating creation of source packages as 'git' is not " 367 u"available") 368 setattr(__Options__, 'noSourcePackages', True) 369 370 return (__Options__, args) 371