2009-05-07 5 views
3

J'ai installé VisualSVN sur mon serveur Windows 2003 et l'ai configuré pour fournir un accès en lecture anonyme. D'après ce que je comprends, VisualSVN utilise Apache et le serveur officiel SVN Repository en dessous.SVN à ZIP à la volée

Maintenant, je voudrais étendre la page Web SVN pour fournir la fonctionnalité "télécharger HEAD comme ZIP". Les portails Web comme SourceForge et Codeplex fournissent cette fonctionnalité.

Y a-t-il un plugin pour le serveur SVN Repository pour cela? Ou peut-être un client Web distinct (de préférence ASP.NET)?

+0

Essayez de poster sur serverfault.com – stukelly

+0

@stukelly - en désaccord; SVN est plus une chose «dev» qu'une chose it-pro. –

+0

@stukelly - Je n'ai pas accès à serverfault.com, et de plus, je suis un développeur et je suis prêt à développer une bonne solution personnalisée. Donc, je ne suis pas seulement après des produits disponibles sur le marché. – tofi9

Répondre

5

J'ai trouvé une solution, et je voudrais le partager avec vous, au cas où quelqu'un d'autre voudrait obtenir la même solution. Après avoir analysé WebSvn, j'ai découvert qu'ils utilisent la fonctionnalité Répertoire d'exportation SVN pour télécharger la source dans un dossier local, puis compresser le répertoire, à la volée. La performance est assez bien.

Ma solution en C# ci-dessous, utilise SharpSVN et DotNetZip. Le code source complet peut être trouvé sur my SVN repository.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using SharpSvn; 
using Ionic.Zip; 
using System.IO; 
using SharpSvn.Security; 

namespace SvnExportDirectory 
{ 
    public class SvnToZip 
    { 
     public Uri SvnUri { get; set; } 
     public string Username { get; set; } 
     public string Password { get; set; } 

     private bool passwordSupplied; 

     public SvnToZip() { } 

     public SvnToZip(Uri svnUri) 
     { 
      this.SvnUri = svnUri; 
     } 

     public SvnToZip(string svnUri) 
      : this(new Uri(svnUri)) { } 

     public void ToFile(string zipPath) 
     { 
      if (File.Exists(zipPath)) 
       File.Delete(zipPath); 

      using (FileStream stream = File.OpenWrite(zipPath)) 
      { 
       this.Run(stream); 
      } 
     } 

     public MemoryStream ToStream() 
     { 
      MemoryStream ms = new MemoryStream(); 
      this.Run(ms); 
      ms.Seek(0, SeekOrigin.Begin); 
      return ms; 
     } 

     private void Run(Stream stream) 
     { 
      string tmpFolder = 
       Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); 

      try 
      { 
       using (SvnClient client = new SvnClient()) 
       { 
        //client.Authentication.Clear(); 
        client.Authentication.UserNamePasswordHandlers += Authentication_UserNamePasswordHandlers; 

        SvnUpdateResult res; 
        bool downloaded = client.Export(SvnTarget.FromUri(SvnUri), tmpFolder, out res); 
        if (downloaded == false) 
         throw new Exception("Download Failed"); 
       } 

       using (ZipFile zipFile = new ZipFile()) 
       { 
        zipFile.AddDirectory(tmpFolder, GetFolderName()); 
        zipFile.Save(stream); 
       } 
      } 
      finally 
      { 
       if (File.Exists(tmpFolder)) 
        File.Delete(tmpFolder); 
      } 
     } 


     private string GetFolderName() 
     { 
      foreach (var potential in SvnUri.Segments.Reverse()) 
      { 
       if (string.Equals(potential, "trunk", StringComparison.InvariantCultureIgnoreCase) == false) 
        return potential; 
      } 
      return null; 
     } 

     void Authentication_UserNamePasswordHandlers(object sender, SvnUserNamePasswordEventArgs e) 
     { 
      if (passwordSupplied) 
      { 
       e.Break = true; 
      } 
      else 
      { 
       if (this.Username != null) 
        e.UserName = this.Username; 

       if (this.Password != null) 
        e.Password = this.Password; 

       passwordSupplied = true; 
      } 
     } 
    } 
} 
1

Je ne sais pas « construit », mais vous pouvez essayer d'écrire une page qui utilise SharpSVN et #ZipLib pour faire le travail ...

Si cela est trop lent, vous pourriez probablement utiliser soit un hook de commit ou un job planifié (toutes les quelques minutes ou quelque chose) pour garder un zip pré-préparé à portée de main quelque part que vous pouvez retourner - en utilisant le truc "créer en nom différent puis renommer quand prêt" pour minimiser le temps est verrouillé/indisponible. Ou nommez-le avec le numéro de révision.

+0

C'est une idée. J'ai cependant à propos de la solution personnalisée à la volée, mais j'avais peur que cela ne fonctionne pas bien. SourceForge utilise-t-il SVN? Ou ont-ils leur propre logiciel qui ne fait que rapprocher SVN? La solution hors ligne est trop de configuration, j'en ai peur. Je veux générer un fichier zip à partir de n'importe quel répertoire que je veux. S'il existe une bonne alternative à SVN qui peut le faire, je suis heureux de changer. – tofi9

0

TortoiseSVN enregistre un protocole enfichable que les navigateurs reconnaîtront. svn: // blahblahblah ... vous pourriez regarder dans cela. Mais alors vous devez utiliser TortoiseSVN ...

+0

Je ne le savais pas, merci pour cela. Mais ce n'est pas la solution à mon problème. Je suis vraiment à la recherche d'une solution côté serveur à utiliser via le Web. Comme SourceForge/Codeplex faire cela. – tofi9

Questions connexes