U VY@sdZddlmZddlmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlZddlmZddlmZdZdZddZddZddZddZ dOddZ!dPddZ"Gdd d ejZ#Gd!d"d"ejZ$Gd#d$d$ej%Z&Gd%d&d&e j'Z(d'd(Z)z&dd)l*m+Z+Gd*d+d+e+j,Z-d,Z.Wne/k rdZ.YnXd-d.Z0d/Z1d0Z2e2e2e1d1Z3e j45e j6dfd2d3Z7Gd4d5d5ejZ8Gd6d7d7ejZ9Gd8d9d9ej:Z;Gd:d;d;ejZd?d?ejZ>z dd@lm?Z?d,Z@e?jAZAe?jBZBWn"e/k rdZ@dZAdZBYnXdAdBZCdCdDZDdEdFZEdGdHZFdQdIdJZGdKdLZHdRdMdNZIejJjKZKdS)Sz4 Utilities with minimum-depends for use in setup.py )unicode_literals)install)logN)develop) easy_install)egg_info)install_scripts)sdist) extra_files)git)options) testr_command)version)zrequirements.txtztools/pip-requires)ztest-requirements.txtztools/test-requirescCsXtjd}|r(tdd|dDSttdttj dj ttj j t tt S)NZPBR_REQUIREMENTS_FILEScss|]}|VqdSNstrip.0fr /packaging.py 5sz)get_requirements_files..,z-pyr)osenvirongettuplesplitlistmapstrsys version_infojoinpathsplitextREQUIREMENTS_FILES)filesrrrget_requirements_files2s  r(cCs:g}||d}|r||||d|||<dS)z5Append a separated list to possibly existing value. N)rappendextendr#)ZconfigkeyZ text_listZ new_valueZ current_valuerrrappend_text_list?s    r.cCsdd|DS)NcSsg|]}tj|r|qSr)rr$existsrrrr Js z!_any_existing..r)Z file_listrrr _any_existingIsr1c CsBt|D]4}t|d }|dW5QRSQRXqgS)Nrr*)r1openreadr)requirements_filesZrequirements_fileZfilrrrget_reqs_from_filesNs  &r6Fc CsF|dkrt}dd}g}t|D]}|r"|dr=\2)resubgroup)matchrrr egg_fragmentZsz(parse_requirements..egg_fragment#z-r ) strip_markersz\s*-e\s+z\s*-e\s+.*#egg=(.*)$ \s*https?:z\s*https?:.*#egg=(.*)$z\s*-f\s+zIndex Locationz#.*$r);rz[pbr] Excluding %s: %s)r(r6r startswith partitionparse_requirements pkg_resourcesZ Requirementparse project_name ValueErrorr8r;r9findr+rinfo) r5r@r<Z requirementslineZreq_filerHreasonZsemi_posrrrrEUsJ           rEcCsj|dkrt}g}t|D]J}td|r,qtd|rN|tdd|qtd|r||q|S)Nz (\s*#)|(\s*$)z \s*-[ef]\s+r)rA)r(r6r8r;r+r9)r5Zdependency_linksrLrrrparse_dependency_linkss     rNc@seZdZdZdZddZdS)InstallWithGitzExtracts ChangeLog and AUTHORS from git then installs. This is useful for e.g. readthedocs where the package is installed and then docs built. rcCst|jtj|Sr) _from_git distributionrrunselfrrrrRs zInstallWithGit.runN__name__ __module__ __qualname____doc__ command_namerRrrrrrOsrOc@seZdZdZdZddZdS) LocalInstallzRuns python setup.py install in a sensible manner. Force a non-egg installed in the manner of single-version-externally-managed, which allows us to install manpages and config files. rcCst|jtj|Sr)rPrQ du_installrrRrSrrrrRs zLocalInstall.runNrUrrrrr[sr[c@seZdZdZdZddZdS) TestrTestz&Make setup.py test do the right thing.testcCstj|dSr)r TestrrRrSrrrrRsz TestrTest.runNrUrrrrr]sr]c@s4eZdZdZeZgZdZddZddZddZ d S) LocalRPMVersionz:Output the rpm *compatible* version string of this packageZ rpm_versioncCs.td|j}tt|dS)Nz[pbr] Extracting rpm version) rrKrQZget_nameprintrZ VersionInfoZsemantic_versionZ rpm_string)rTnamerrrrRs  zLocalRPMVersion.runcCsdSrrrSrrrinitialize_optionssz"LocalRPMVersion.initialize_optionscCsdSrrrSrrrfinalize_optionssz LocalRPMVersion.finalize_optionsN) rVrWrXrY descriptionZ user_optionsrZrRrcrdrrrrr`sr`cCstjSr)r have_testrrrrrrfsrf)commandsc@seZdZdZdZddZdS)NoseTestz)Fallback test runner if testr is a no-go.r^cCstj|dSr)rg nosetestsrRrSrrrrRsz NoseTest.runNrUrrrrrhsrhTcCstSr) _have_noserrrr have_nosesrka5#PBR Generated from %(group)r import threading from %(module_name)s import %(import_target)s if __name__ == "__main__": import argparse import socket import wsgiref.simple_server as wss my_ip = socket.gethostbyname(socket.gethostname()) parser = argparse.ArgumentParser( description=%(import_target)s.__doc__, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--port', '-p', type=int, default=8000, help='TCP port to listen on') args = parser.parse_args() server = wss.make_server('', args.port, %(invoke_target)s()) print("*" * 80) print("STARTING test server %(module_name)s.%(invoke_target)s") url = "http://%%s:%%d/" %% (my_ip, server.server_port) print("Available at %%s" %% url) print("DANGER! For testing only, do not use in production") print("*" * 80) server.serve_forever() else: application = None app_lock = threading.Lock() with app_lock: if application is None: application = %(invoke_target)s() z# PBR Generated from %(group)r import sys from %(module_name)s import %(import_target)s if __name__ == "__main__": sys.exit(%(invoke_target)s()) )Zconsole_scriptsZ gui_scriptsZ wsgi_scriptsc cstd||}tD]n\}}||D]V\}}|jrHt|jdkrPtd|t||j |jdd |jd}|||fVq,qdS)z$Override entrypoints console_script.r)r?zBScript targets must be of the form 'func' or 'Class.class_method'.r.)r: module_nameZ import_targetZ invoke_targetN) rZget_script_headerENTRY_POINTS_MAPitemsZ get_entry_mapZattrslenrIdictrmr#) dist executable is_wininstheaderr:templaterbZepZ script_textrrroverride_get_script_args6s rwc@seZdZdZddZdS) LocalDeveloprcCs:tjdkrtj||S|js6t|D]}|j|q&dS)NZwin32)r!platformrinstall_wrapper_scriptsZexclude_scriptsrw write_script)rTrrargsrrrrzLs   z$LocalDevelop.install_wrapper_scriptsN)rVrWrXrZrzrrrrrxHsrxc@seZdZdZdZddZdS)LocalInstallScriptsz(Intercepts console scripts entry_points.rc Csddl}|d|jjr,|jjj|ng|_|jr    zLocalInstallScripts.runNrUrrrrr}Tsr}c@s eZdZdZddZddZdS)LocalManifestMakerz?Add any files that are in git and some standard sensible files.cCsdD]}|j|qdS)N)zinclude AUTHORSzinclude ChangeLogzexclude .gitignorezexclude .gitreviewzglobal-exclude *.pyc)filelistZprocess_template_line)rTZ template_linerrr_add_pbr_defaultssz$LocalManifestMaker._add_pbr_defaultscCs|jd}tj||j|j|j|j|jt t |dd}|spt }|r|j|ntj|jr||d}||jjd|jddS)NpbrZskip_git_sdistZSKIP_GIT_SDISTr*)prefix)rQget_option_dictr add_defaultsrr+rvmanifestr,r Zget_extra_filesr Zget_boolean_optionr Z_find_git_filesrr$r/Z read_manifestrrZinclude_patternr)rT option_dictZ should_skipZrcfilesrrrrrs"   zLocalManifestMaker.add_defaultsN)rVrWrXrYrrrrrrr|s rc@seZdZdZdZddZdS) LocalEggInfozAOverride the egg_info command to regenerate SOURCES.txt sensibly.rcCstj|jd}tj|r2tjds2dtjkr^tdt |j }||_ | |j |_ n:tdt|_ t|ddD]}|j |qdS) apGenerate SOURCES.txt only if there isn't one already. If we are in an sdist command, then we always want to update SOURCES.txt. If we are not in an sdist command, then it doesn't matter one flip, and is actually destructive. However, if we're in a git context, it's always the right thing to do to recreate SOURCES.txt z SOURCES.txtz.gitr z[pbr] Processing SOURCES.txtz"[pbr] Reusing existing SOURCES.txtr2r*N)rr$r#rr/r!argvrrKrrQrrRrZFileListr3r4rr+)rTZmanifest_filenameZmmentryrrr find_sourcess        zLocalEggInfo.find_sourcesN)rVrWrXrYrZrrrrrrsrcCs>|d}t}|r t|}tj||dtj|ddS)Nr)r changelog)r)rr _iter_log_onelineZ_iter_changelogZwrite_git_changelogZgenerate_authors)rQrrrrrrPs   rPc@seZdZdZdZddZdS) LocalSDistz5Builds the ChangeLog and Authors files from VC first.r cCst|jtj|dSr)rPrQr rRrSrrrrRs zLocalSDist.runNrUrrrrrsr)builddoccCstSr) _have_sphinxrrrr have_sphinxsrc si|r|d}nd}td|g|}tdfdd|dD}t}|D]}|dd|d DqPfd d }|d |d |d|d|d|d|d|d|D]}td|qd dS)aCalculate the sort of semver increment needed from git history. Every commit from HEAD to tag is consider for Sem-Ver metadata lines. See the pbr docs for their syntax. :return: a dict of kwargs for passing into SemanticVersion.increment. z..HEADZHEADr sem-ver:cs*g|]"}|dr|dqS)rN)lowerrCr)rrL) header_lenrrr0sz)_get_increment_kwargs..r*cSsg|] }|qSrr)rsymbolrrrr0srcs||krd|<||dS)NT)discard)rsymbolsZimpact)resultrr_handle_symbolsz-_get_increment_kwargs.._handle_symbolZbugfixZpatchZfeatureminorZ deprecationz api-breakmajorz[pbr] Unknown Sem-Ver symbol %rN) r _run_git_commandrprsetupdaterrKpop) git_dirtagZ version_specrrgrrrrr)rrr_get_increment_kwargss&       rc Cstj|d}d}t|D]f\}\}}}t}t|D]0}z|tj|Wq4t k rbYq4Xq4|rt | |fSqd|fS)zReturn the commit data about the most recent tag. We use git-describe to find this out, but if there are no tags then we fall back to counting commits since the beginning of time. )rrr)) r r enumeraterraddrSemanticVersionfrom_pip_string Exceptionmaxrelease_string)rrZ row_countZignoredZtag_setZ version_tagsrrrr_get_revno_and_last_tags  rcCst|\}}tj|pd}|dkr*|}n|jft||}|dk r`||kr`tdt||d|dkrl|S||}|dk r||}||kr|S|S)aCalculate a version from a target version in git_dir. This is used for untagged versions only. A new version is calculated as necessary based on git metadata - distance to tags, current hash, contents of commit messages. :param git_dir: The git directory we're working from. :param target_version: If None, the last tagged version (or 0 if there are no tags yet) is incremented as needed to produce an appropriate target version following semver rules. Otherwise target_version is used as a constraint - if semver rules would result in a newer version then an exception is raised. :return: A semver version object. 0rNzRgit history requires a target version of %(new)s, but target version is %(target)s)newtarget) rrrrZ incrementrrIrqZto_dev)rtarget_versionrZdistanceZ last_semverZ new_versionZnew_devZ target_devrrr_get_version_from_git_targets*    rcCst}|rvz,tjddg|dddd}tj|}Wn*tk rb|rZtj|}nd}YnXt||}| Szt WSt k rYdSXdS) aCalculate a version string from git. If the revision is tagged, return that. Otherwise calculate a semantic version description of the tree. The number of revisions since the last tag is included in the dev counter in the version for untagged versions. :param pre_version: If supplied use this as the target version rather than inferring one from the last tag + commit messages. Zdescribez --exact-matchT)Zthrow_on_error-rlNr)) r Z_run_git_functionsrreplacerrrrrrZunicode NameError) pre_versionrZtaggedrrrrr_get_version_from_git>s0   rc Csddg}i}|D]Z}zt|d}Wnttfk r>YqYnXzt|}Wqtjk rhYqYqXq|dd|krdS|ddS)zGet the version from package metadata if present. This looks for PKG-INFO if present (for sdists), and if not looks for METADATA (for wheels) and failing that will return None. zPKG-INFOZMETADATAr2NameNZVersion)r3IOErrorOSErroremailZmessage_from_fileZ MessageErrorr) package_nameZpkg_metadata_filenamesZ pkg_metadatafilenameZpkg_metadata_filerrr_get_version_from_pkg_metadatads  rcCsdtjdtjdd}|r |St|}|r0|St|}tjddkrP|d}|rX|StddS)aGet the version of the project. First, try getting it from PKG-INFO or METADATA, if it exists. If it does, that means we're in a distribution tarball or that install has happened. Otherwise, if there is no PKG-INFO or METADATA file, pull the version from git. We do not support setup.py version sanity in git archive tarballs, nor do we support packagers directly sucking our git repo into theirs. We expect that a source tarball be made from our git repo - or that if someone wants to make a source tarball from a fork of our repo with additional tags in it that they understand and desire the results of doing that. :param pre_version: The version field from setup.cfg - if set then this version will be the next release. Z PBR_VERSIONZOSLO_PACKAGE_VERSIONNrr?zutf-8zVersioning for this project requires either an sdist tarball, or access to an upstream git repository. Are you sure that git is installed?) rrrrrr!r"encoder)rrrrrr get_version|s  r)NF)N)N)N)LrYZ __future__rZdistutils.commandrr\rrrrr8r!rFZ setuptoolsZsetuptools.commandrrrrr rr r r Z pbr.pbr_jsonr rr&ZTEST_REQUIREMENTS_FILESr(r.r1r6rErNrOr[r_r]ZCommandr`rfZnosergrirhrj ImportErrorrkZ _wsgi_textZ _script_textrnr$normpathrsrwrxr}Zmanifest_makerrrrPrrrZ LocalBuildDocZLocalBuildLatexrrrrrrrZpbr_jsonZwrite_pbr_jsonrrrrs                 @     &   (!     %% & )