¿Cómo properties desde el elemento SVN en el repository?

Puedo conectarme a un repository

var client: TSvnClient; url: string; begin BaseDllDir := ExtractFilePath(ParamStr(0))+'Subversion'; //dlls sitting in "Subversion" folder client := TSvnClient.Create; client.Initialize; url := 'https://repos.wowace.com/wow/bank-items/tags/6.1.0.0'; 

Puedo usar las funciones básicas de client.List para get una list de elementos:

 var sl: TStrings; begin sl := TStringList.Create; client.List(Url, svnDepthImmediates, False, sl); Log(sl.Text); 

Y eso me devuelve la list del elemento en sí, y sus files inmediatos y inputs de directory:

 .=/tags/6.1.0.0 .pkgmeta=/tags/6.1.0.0/.pkgmeta BankItems.lua=/tags/6.1.0.0/BankItems.lua BankItems.toc=/tags/6.1.0.0/BankItems.toc Bindings.xml=/tags/6.1.0.0/Bindings.xml localization-deDE.lua=/tags/6.1.0.0/localization-deDE.lua localization-enUS.lua=/tags/6.1.0.0/localization-enUS.lua ...snip... 

También puedo usar TSvnList.LoadList para get una list de objects TSvnListItem :

 var list: TSvnList; item: TSvnListItem; begin list := TSvnList.Create(client); list.LoadList(Url, svnDepthImmediates, False); s := ''; for i := 0 to list.Count-1 do begin li := list.Items[i]; s := s+ '- Item '+intToStr(i)+#13#10+ ' - **Path**: '+li.Path+#13#10+ ' - **AbsolutePath**: '+li.AbsolutePath+#13#10+ ' - **Size**: '+IntToStr(li.Size)+#13#10+ ' - **Kind**: '+SvnNodeKindString(li.Kind)+#13#10+ ' - **HasProps**: '+IfThen(li.HasProps, 'Yes', 'No')+#13#10+ ' - **LastAuthor**: '+li.LastAuthor+#13#10+ ' - **Time**: '+DateTimeToStr(li.Time)+#13#10+ ' - **CreatedRevision**: '+IntToStr(li.CreatedRevision)+#13#10+#13#10; end; Log(s); 
  • Artículo 0

    • Ruta :
    • AbsolutePath : /tags/6.1.0.0
    • Tamaño : 0
    • Tipo : svnNodeDir
    • HasProps : No
    • LastAuthor : nbluewiz
    • Hora : 25/02/2015 10:13:29 PM
    • CreadoRevisión : 227
  • Artículo 1

    • Ruta : .pkgmeta
    • AbsolutePath : /tags/6.1.0.0
    • Tamaño : 22
    • Tipo : svnNodeFile
    • HasProps : No
    • LastAuthor : raíz
    • Hora : 29/09/2008 5:33:49 PM
    • CreadoRevisión : 96
  • Artículo 2

    • Ruta : BankItems.lua
    • AbsolutePath : /tags/6.1.0.0
    • Tamaño : 272471
    • Tipo : svnNodeFile
    • HasProps : Sí
    • LastAuthor : burstroc
    • Hora : 2/8/2015 11:46:51 PM
    • CreadoRevisión : 225
  • Artículo 3

    • Ruta : BankItems.toc
    • AbsolutePath : /tags/6.1.0.0
    • Tamaño : 1776
    • Tipo : svnNodeFile
    • HasProps : Sí
    • LastAuthor : burstroc
    • Hora : 25/02/2015 9:02:47 PM
    • CreadoRevisión : 226

…recorte…

Lo cual es una forma larga de decir que puedo conectarme con éxito a un repository y consultar cosas.

Ahora para las properties

Ahora quiero leer algunas properties de los artículos en el repository; o algunos metadatos más avanzados.

Observa que la class TSvnListItem tiene una propiedad HasProps ; pero no hay manera de leer las properties. Para eso creo que necesitamos el object TSvnItem :

 TSvnItem = class public //...snip... property SvnPathName: string; property URL: string; property Parent: TSvnItem; property PathName: string; property LastCommitAuthor: string; property LastCommitRevision: Integer; property LastCommitTime: TDateTime; property PropCount: Integer; property PropNames[Index: Integer]: string; property HistoryCount: Integer; property HistoryItems[Index: Integer]: TSvnHistoryItem; end; 

Dado un artículo arbitrario, seguro sería bueno get la URL de su padre. O para get el historial o las properties:

 item := TSvnItem.Create(client, Url); s := ''; for i := 0 to item.PropCount-1 do begin s := s+'"'+item.PropNames[i]+'" = "'+item.PropValueFromIndex[i]+'"'+#13#10; end; Log(s); 

Excepto que cualquier bash de acceder a algo utilizando TSvnItem da TSvnItem resultado el error:

C: \ Archivos de progtwig (x86) \ Contoso \ Grobber no es una copy de trabajo.

Cual es verdad; no lo es

Hay otras sobrecargas de TSvnItem.Create , una de las cuales se usa aquí con aparente éxito:

 item := TSvnItem.Create(client, nil, Url); 

Pero ese constructor falla con:

La ruta dada está mal formateada o contiene caracteres no válidos

Falla dentro del constructor en:

 FSvnPathName := FSvnClient.NativePathToSvnPath(FPathName, SubPool); 

Que a su vez falla en

 function TSvnClient.NativePathToSvnPath(const NativePath: string; SubPool: PAprPool = nil): string; begin //...snip... AprCheck(apr_filepath_merge(SvnPath, '', PAnsiChar(UTF8Encode(NativePath)), APR_FILEPATH_TRUENAME, SubPool)); 

Y entonces estoy perplejo. Sin documention en la biblioteca de Delphi Svn estoy … perplejo.

Ejemplo mínimo reproducible

La URL es pública y está abierta para que cualquiera pueda usarla:

https://repos.wowace.com/wow/bank-items/tags/6.1.0.0/BankItems.lua

Pero deberá asegurarse de suministrar todos los Dlls:

 program Project1; {$APPTYPE CONSOLE} uses System.SysUtils, SvnClient; var client: TSvnClient; item: TSvnItem; begin try client := TSvnClient.Create; BaseDllDir := ExtractFilePath(ParamStr(0)); client.Initialize; item := TSvnItem.Create(client, nil, 'https://repos.wowace.com/wow/bank-items/tags/6.1.0.0/BankItems.lua'); Writeln('ItemCount: '+IntToStr(item.PropCount)); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. 

Tenga en count el comentario sobre la sobrecarga de URL en SvnClient (1.9).

{TSvnItem for URLs es una especie de hack y en este momento no esperes que funcione nada más que carga de historia asincrónica} constructor Create (ASvnClient: TSvnClient; const AURL: string); sobrecarga;

Funciona con Working Dir

 procedure TForm1.btLoadPropClick(Sender: TObject); const url = 'svn://hub/vcl/Trunk/Jedi/'; WorkDir = 'D:\VCL\Jedi'; var i: Integer; item: TSvnItem; begin item := TSvnItem.Create(FClient, nil, WorkDir); Memo1.Lines.Add('============== Props ============================'); for i := 0 to Pnetworking(item.PropCount) do begin Memo1.Lines.Add(item.PropNames[i] + '" = "' + item.PropValueFromIndex[i]); end; item.Free; end; 

Editar: Parece haber un error en TSvnItem.ReloadProps en la línea 2085:

Cambiar la línea 2085 al código siguiente parece resolver el problema:

  AprCheck(apr_filepath_merge(TruePath, PAnsiChar(UTF8Encode(URL)), PAnsiChar(UTF8Encode(FPathName)), APR_FILEPATH_TRUENAME, SubPool));