o k`M@sddlZddlmZddlTddlmZmZddlmZddl m Z ddl m Z m Z ddlmZdd lmZmZdd lmZdd lmZGd d d eZGdddeZddZddZddZdddZGdddeZdS)N) ConfigSection)*) NoSuchNodeRepositoryManager)IPropertyRenderer)IPropertyDiffRenderer)Ranges to_ranges)tag)_tag_)chrome_resource_path)_path_within_scopec@s^eZdZeeeddddidZddZdd Zd d Z d d Z ddZ ddZ ddZ dS)SubversionPropertyRenderer svn:externalsaThe TracBrowser for Subversion can interpret the `svn:externals` property of folders. By default, it only turns the URLs into links as Trac can't browse remote repositories. However, if you have another Trac instance (or an other repository browser like [http://www.viewvc.org/ ViewVC]) configured to browse the target repository, then you can instruct Trac which other repository browser to use for which external URL. This mapping is done in the `[svn:externals]` section of the TracIni. Example: {{{ [svn:externals] 1 = svn://server/repos1 http://trac/proj1/browser/$path?rev=$rev 2 = svn://server/repos2 http://trac/proj2/browser/$path?rev=$rev 3 = http://theirserver.org/svn/eng-soft http://ourserver/viewvc/svn/$path/?pathrev=25914 4 = svn://anotherserver.com/tools_repository http://ourserver/tracs/tools/browser/$path?rev=$rev }}} With the above, the `svn://anotherserver.com/tools_repository/tags/1.1/tools` external will be mapped to `http://ourserver/tracs/tools/browser/tags/1.1/tools?rev=` (and `rev` will be set to the appropriate revision number if the external additionally specifies a revision, see the [%(svnbook)s SVN Book on externals] for more details). Note that the number used as a key in the above section is purely used as a place holder, as the URLs themselves can't be used as a key due to various limitations in the configuration file parser. Finally, the relative URLs introduced in [http://subversion.apache.org/docs/release-notes/1.5.html#externals Subversion 1.5] are not yet supported. svnbookz>http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html)doc_argscCs i|_dSN)_externals_map)selfrE/usr/lib/python3/dist-packages/tracopt/versioncontrol/svn/svn_prop.py__init__Is z#SubversionPropertyRenderer.__init__cCs|dvrdS|dvr dSdS)N)rsvn:needs-lock svn:mergeinfosvnmerge-blockedsvnmerge-integratedrrrnamemoderrrmatch_propertyNs  z)SubversionPropertyRenderer.match_propertycCsN|dkr |||S|dkr||S|dks|dr%|||||SdS)Nrrr svnmerge-)_render_externals_render_needslock startswith_render_mergeinfo)rr!r"contextpropsrrrrender_propertyTs z*SubversionPropertyRenderer.render_propertycCs |od|vS)Nz://r)rurlrrr _is_abs_url\s z&SubversionPropertyRenderer._is_abs_urlc CsR|js4|jD]+\}}|}t|dkr|jd|q|\}}|dddddd|j|<qg}|D]}|}|sCq:|d d |d }} } | d r_| |ddddfq:t|d kro|d} | dd } | | s| |ddddfq:g} | } | r| |jvs| dkrnt | \} } | | | s|j | }| rd| nd }|s| ds| dr| dd}|rd }| rt jt| }| ||| |||| dfq:| ||| ddfq:g}|D]5\}} } }}|}| durd }n|r| rd| } || | 7}d || | f}ntd}| |||fqtdd|DS)NrzRsvn:externals entry %s doesn't contain a space-separated key value pair, skipping.%z%%z$pathz%(path)sz$revz%(rev)sr#z-r/z at revision zhttp://zhttps://)pathrevz in z'No svn:externals configured in trac.inic Ss(g|]\}}}ttj|||dqS))hreftitle)r lia).0labelr7r8rrr z@SubversionPropertyRenderer._render_externals..)rsvn_externals_sectionoptionssplitlenlogwarningreplace splitlinesr'appendr- posixpathgetjoinreversedr r ul)rpropdummykeyvaluekey externalsexternalelements localpathr6r,prefixbase_urlprefr7revstr remotepathexternals_datar<r8rrrr%_s               z,SubversionPropertyRenderer._render_externalscCs$t|jd}tj|tdtddS)Nzcommon/lock-locked.pngz needs lock)srcaltr8)r reqr imgr )rr)r,rrrr&s z,SubversionPropertyRenderer._render_needslockc Csg}||D]0}z|dd\}}|t|t|ddgWqty8|tj|ddYqwtjtdd|Dd d S) N:r3,,​rcolspancSg|]}t|qSrr tr)r;rowrrrr=z@SubversionPropertyRenderer._render_mergeinfo..r*class_) rFrsplitrGr tdrE ValueErrortabletbody) rr!r"r)r*rowsrgr5revsrrrr(s  z,SubversionPropertyRenderer._render_mergeinfoN)__name__ __module__ __qualname__ implementsrrr?rr#r+r-r%r&r(rrrrr!s!$A rc@$eZdZeeddZddZdS)SubversionMergePropertyRenderercC|dvrdSdSNrrrrr rrrr# z.SubversionMergePropertyRenderer.match_propertyc! Cs|dv}|dr tdntd}|rdnd}|jjj}|jj} t|j|} |jj} |rI| | | } i} | D]\}}|| vrH|d| |<q:g}g}| drY|| }n|| }|D]}| dd\}}t| j|}|durvqa|}t|\}}d |}d }z| || } |jjd |}d ||vr&t||t||||g}|rd |}|ttd |||td|r| |}|s| }tt|pd| d}|tt|8}t|||}|r|tt|8}|r| |t|} ||| ||fWqat|}|ttd||||d |dd|DfWqaWn t y3d}Ynw|!d d}|||t"#d|t"j#||dgfqai}dd|D}|r`| $|}|D]4\}} }}||vrv|t||M}n|%|ttd||t||d |dd|Dfqb|sdS|&|r|ddrt"j'tdddd} nd} t"| t"j(t")dd|Ddd S)!zParse svn:mergeinfo and svnmerge-* properties, converting branch names to links and providing links to the revision log for merged and eligible revisions. )rrblockedmergedrNr3r$r_r`FsourceLOG_VIEWznon-inheritablez,merged on the directory itself but not beloweligiblecSrdrr rlr;eachrrrr=rhzCSubversionMergePropertyRenderer.render_property..Trar4rbcSs g|] \}}}}|t|fqSr)min)r;spathnoderrgrrrr=s cSrdrrrrrrr= rhr0rz(toggle deleted branches)ztrac-toggledeletedr1)rjr7cSs(g|]\}}}tj||rdnddqS)z trac-deletedNrire)r;deletedrrgrrrr=r>r*ri)*endswithr resourceparentidrenvget_repositoryversionget_nodeget_copy_ancestryr'rArFrscopestrip_partition_inheritablerJchildperm_get_source_link_get_revs_linkrGrIget_branch_originsetranger_get_blocked_revsmaxr rrEr rl_get_changed_revsclearsortr:rnro)!rr!r"r)r* has_eligible revs_label revs_colsreponame target_pathrepos target_revr branch_startsr5r6rpeligible_infossourceslinerqr inheritablenon_inheritablerrrg first_revrr{ changed_revs changed_nodes toggledeletedrrrr+s                    z/SubversionMergePropertyRenderer.render_propertyN)rrrsrtrurr#r+rrrrrw rwcCsPgg}}|dD]}|r|ddkr||ddq ||q ||fS)z?Non-inheritable revision ranges are marked with a trailing '*'.r`r0rN)rArG)rqrrrrrrrs  rc Csj|dkr |dd}ndS|D]!}z|dd\}}|d|kr(|WSWqty2YqwdS)zXReturn the revisions blocked from merging for the given property name and path. rrr/r_r3r4)rIrFrAr Exception)r*r!r5rMrprqrrrr's   rcCs8|jjj}tjd|td|jj|pd||jjddS)z Return a link to a merge source.r4zView merge sourceN)r6r8r7) rrrr r:r r7browserr)rr)rrrrr8s rcCs|jjj}|stj|tddSd|vsd|vr$|jj|pd||d}n |j||p+d|}| dd}|r>td||d }n|}tj |||d S) zReturn a link to the revision log when more than one revision is given, to the revision itself for a single revision, or a `` with "no revision" for none. z No revisions)r8r`-N)rqz, z%(title)s: %(revs)s)r8rqr) rrrr spanr r7rC changesetrEr:)r<r)rrqr8r revs_hrefrrrr?s  rc@rv)#SubversionMergePropertyDiffRenderercCrxryr)rr!rrrmatch_property_diffXrzz7SubversionMergePropertyDiffRenderer.match_property_diffc# st|j}||jjjfdd}||} ||} d} tdtdg| } tdtdg| } td}td }g}i}g}| D]`\\}}| v}|rYt }}n| \}}||}||}|sm|smqG||}||}t ||B|B|B}z |d }| ||d fWn tyYnw| |||||fqG|r|}fd d }g}|D]c\}}}}}|vrt |}||M}||M}||M}||M}|s|r|rtd} nd} | t|| g|ot| ||||ot| ||||ot|||||ot||||fqg}!| D]\}|! t|fq#|s9|!rW||!tjtdd|Ddd|!Ddd}"nttd}"ttdtd|"S)Nc s~i}|}dkr|n|}|D](}|dd\}}tj|}|dur.parse_sourcesr{zmerged: z blocked: zreverse-merged: z un-blocked: zmarked as non-inheritable: zunmarked as non-inheritable: r0rcs&|rt|}t|dd||SdS)Nr`ra)r rrE)rqr))rrr revs_links  zKSubversionMergePropertyDiffRenderer.render_property_diff..revs_linkz (added)cSs(g|]}tdd|ddDqS)css|]}t|VqdSrr)r;crrr szVSubversionMergePropertyDiffRenderer.render_property_diff...r3Nre)r;colsrrrr=s zLSubversionMergePropertyDiffRenderer.render_property_diff..c Ss0g|]\}}tt|tjtdddqS)removedrrb)r rfrlr )r;rr[rrrr=s$r*riz# (with no actual effect on merging)zProperty %(prop)s changed)rM)rrrrrrrr itemsrpopsortedrrGrrrr rrnroemr9r strong)#rr! old_context old_props new_context new_propsr@rmr old_sources new_sourcesr{ added_label removed_labeladded_ni_labelremoved_ni_labelrrrnew_revs new_revs_ni new_spathold_revs old_revs_niaddedradded_ni removed_nirqrrmodified_sourcesstatusremoved_sourceschangesr)r!rrrrender_property_diff\s               z8SubversionMergePropertyDiffRenderer.render_property_diffN)rrrsrtrurrrrrrrrSrrr)rH trac.configr trac.coretrac.versioncontrol.apirr"trac.versioncontrol.web_ui.browserr$trac.versioncontrol.web_ui.changesetr trac.utilrr trac.util.htmlr trac.util.translationr r trac.web.chromer !tracopt.versioncontrol.svn.svn_fsr Componentrrwrrrrrrrrrs&      l