private Process SwitchedExecuteSvnLook(SvnLookCommand command, String arguments) { if (RevisionOrTransaction is int) { return(SvnLook.Execute(command, (int)RevisionOrTransaction, arguments)); } else if (RevisionOrTransaction is Transaction) { return(SvnLook.Execute(command, (Transaction)RevisionOrTransaction, arguments)); } // Due to constructor logic we can never actually reach this point throw new InvalidOperationException("RevisionOrTransaction is not a valid type"); }
static int Main(string[] args) { try { // Fetch paths and transaction from configuration and arguments String svnlookPath = ConfigurationSettings.AppSettings["svnlook.location"]; String repositoryPath = args[0]; String transactionString = args[1]; Transaction transaction = Transaction.Parse(transactionString); // Initialize a WindsorContainer with all the relevant hooks // and repository. WindsorContainer container = new WindsorContainer(new XmlInterpreter(new AppDomainConfigSource("castle"))); IRepository repository = new DefaultRepository( svnlookPath, repositoryPath, transaction); container.Kernel.AddComponentInstance("Repository", typeof(IRepository), repository); // Fetch all the hooks from the container, if we get none // we dont need to process the files in the transaction // and can simply exit the program with success at this point. IPreCommit[] hooks = FetchHooks(container.Kernel); if (hooks.Length == 0) return 0; // Start processing all the files commited and run the hooks // on them. This is done by executing a changed command on // svnlook and parsing the result for the files/directories. bool hooksOK = true; Regex lineRegex = new Regex("^(?<contents>[AUD_])(?<properties>[U ]) +(?<file>[^ ].*) *$"); SvnLook svnLook = new SvnLook(svnlookPath, repositoryPath); using(Process process = svnLook.Execute(SvnLookCommand.Changed, transaction, null)) { String line; while((line = process.StandardOutput.ReadLine()) != null) { Match m = lineRegex.Match(line); if(!m.Success) { Console.Error.WriteLine("Could not match line: " + line); return 3; } if(m.Groups["file"].Value.EndsWith("/")) { // This is a directory, not a file. // TODO: Add directory handling } else { RepositoryStatus contentsStatus; RepositoryStatus propertiesStatus; switch (m.Groups["contents"].Value) { case "A": contentsStatus = RepositoryStatus.Added; break; case "U": contentsStatus = RepositoryStatus.Updated; break; case "D": contentsStatus = RepositoryStatus.Deleted; break; case "_": contentsStatus = RepositoryStatus.Unchanged; break; default: Console.Error.WriteLine("Could not match status flags for contents on line: " + line); return 3; } switch (m.Groups["properties"].Value) { case "U": propertiesStatus = RepositoryStatus.Updated; break; case " ": propertiesStatus = RepositoryStatus.Unchanged; break; default: Console.Error.WriteLine("Could not match status flags for properties on line: " + line); return 3; } using(RepositoryFile file = new RepositoryFile(repository, m.Groups["file"].Value, contentsStatus, propertiesStatus)) { // If HooksAllow returns false we should not allow // the transaction, but rather than exiting we store // that fact in a boolean so that the user will be // told all errors his files contain rather than just // one at a time. hooksOK &= HooksAllow(file, hooks); } } } if (!hooksOK) return 1; } return 0; } catch(Exception e) { Console.Error.WriteLine("An uncaught exception was thrown in the hook implementation"); Console.Error.WriteLine(e.Message); return 2; } }
static int Main(string[] args) { try { // Fetch paths and transaction from configuration and arguments String svnlookPath = ConfigurationSettings.AppSettings["svnlook.location"]; String repositoryPath = args[0]; String transactionString = args[1]; Transaction transaction = Transaction.Parse(transactionString); // Initialize a WindsorContainer with all the relevant hooks // and repository. WindsorContainer container = new WindsorContainer(new XmlInterpreter(new AppDomainConfigSource("castle"))); IRepository repository = new DefaultRepository( svnlookPath, repositoryPath, transaction); container.Kernel.AddComponentInstance("Repository", typeof(IRepository), repository); // Fetch all the hooks from the container, if we get none // we dont need to process the files in the transaction // and can simply exit the program with success at this point. IPreCommit[] hooks = FetchHooks(container.Kernel); if (hooks.Length == 0) { return(0); } // Start processing all the files commited and run the hooks // on them. This is done by executing a changed command on // svnlook and parsing the result for the files/directories. bool hooksOK = true; Regex lineRegex = new Regex("^(?<contents>[AUD_])(?<properties>[U ]) +(?<file>[^ ].*) *$"); SvnLook svnLook = new SvnLook(svnlookPath, repositoryPath); using (Process process = svnLook.Execute(SvnLookCommand.Changed, transaction, null)) { String line; while ((line = process.StandardOutput.ReadLine()) != null) { Match m = lineRegex.Match(line); if (!m.Success) { Console.Error.WriteLine("Could not match line: " + line); return(3); } if (m.Groups["file"].Value.EndsWith("/")) { // This is a directory, not a file. // TODO: Add directory handling } else { RepositoryStatus contentsStatus; RepositoryStatus propertiesStatus; switch (m.Groups["contents"].Value) { case "A": contentsStatus = RepositoryStatus.Added; break; case "U": contentsStatus = RepositoryStatus.Updated; break; case "D": contentsStatus = RepositoryStatus.Deleted; break; case "_": contentsStatus = RepositoryStatus.Unchanged; break; default: Console.Error.WriteLine("Could not match status flags for contents on line: " + line); return(3); } switch (m.Groups["properties"].Value) { case "U": propertiesStatus = RepositoryStatus.Updated; break; case " ": propertiesStatus = RepositoryStatus.Unchanged; break; default: Console.Error.WriteLine("Could not match status flags for properties on line: " + line); return(3); } using (RepositoryFile file = new RepositoryFile(repository, m.Groups["file"].Value, contentsStatus, propertiesStatus)) { // If HooksAllow returns false we should not allow // the transaction, but rather than exiting we store // that fact in a boolean so that the user will be // told all errors his files contain rather than just // one at a time. hooksOK &= HooksAllow(file, hooks); } } } if (!hooksOK) { return(1); } } return(0); } catch (Exception e) { Console.Error.WriteLine("An uncaught exception was thrown in the hook implementation"); Console.Error.WriteLine(e.Message); return(2); } }