Exemple #1
0
		[Test] public void BinaryWithContents()
		{
			RepositoryFile file = new RepositoryFile(repository, BINARY_WITH_CONTENTS_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Stream stream = file.GetContents();

		}
Exemple #2
0
		[Test] public void CSharpMimeSet()
		{
			RepositoryFile file = new RepositoryFile(repository, CSHARP_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("text/cs", file.MimeType, "RepositoryFile.MimeType does not return the svn:mime-type");
			Assert.IsTrue(file.IsText, "RepositoryFile.IsText does not return true when svn:mime-type starts with \"text/\"");

		}
Exemple #3
0
		[Test] public void NoMimeTypeSet()
		{
			RepositoryFile file = new RepositoryFile(repository, NO_MIME_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("text/plain", file.MimeType, "RepositoryFile.MimeType does not return \"text/plain\" when svn:mime-type is not set");
			Assert.IsTrue(file.IsText, "RepositoryFile.IsText does not return true when svn:mime-type is not set");

		}
		[Test] public void Deleted()
		{

			using(RepositoryFile file = new RepositoryFile(new MockRepository(null), "File.cs", RepositoryStatus.Deleted, RepositoryStatus.Unchanged))
			{
				Error[] errors = hook.PreCommit(file);

				Assert.AreEqual(0, errors.Length);
			}

		}
Exemple #5
0
		[Test] public void Contents()
		{
			RepositoryFile file = new RepositoryFile(repository, CONTENTS_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			using(Stream stream = file.GetContents())			
			using(TextReader reader = new StreamReader(stream))
			{
				
				Assert.AreEqual("This is the first line", reader.ReadLine());
				Assert.AreEqual("Second Line...", reader.ReadLine());
				Assert.AreEqual("And the third", reader.ReadLine());
				Assert.AreEqual("", reader.ReadLine());
				Assert.AreEqual("Final line!", reader.ReadLine());
				Assert.AreEqual(null, reader.ReadLine());

			}

		}
Exemple #6
0
		private static bool HooksAllow(RepositoryFile file, IPreCommit[] hooks)
		{
			bool hooksOK = true;
			foreach (IPreCommit hook in hooks)
			{
				Error[] errors = hook.PreCommit(file);
				if(errors != null && errors.Length > 0)
				{
					hooksOK = false;
					Console.Error.WriteLine("An error occured in \"{0}\"", file);
					foreach(Error error in errors)
					{						
						Console.Error.WriteLine(error.Description);
					}
				}
			}

			return hooksOK;
		}
Exemple #7
0
        private static bool HooksAllow(RepositoryFile file, IPreCommit[] hooks)
        {
            bool hooksOK = true;

            foreach (IPreCommit hook in hooks)
            {
                Error[] errors = hook.PreCommit(file);
                if (errors != null && errors.Length > 0)
                {
                    hooksOK = false;
                    Console.Error.WriteLine("An error occured in \"{0}\"", file);
                    foreach (Error error in errors)
                    {
                        Console.Error.WriteLine(error.Description);
                    }
                }
            }

            return(hooksOK);
        }
		public Error[] PreCommit(RepositoryFile file)
		{
			// Check files that have the proper extension
			// but skip the files that are deleted
			if (file.ContentsStatus == RepositoryStatus.Deleted ||
				Array.IndexOf(extensions, file.Extension) == -1)
			{
				return Error.NoErrors;
			}

			ArrayList errors = new ArrayList();

			String[] props = file.GetProperty("svn:eol-style");

			if (props == null || props.Length == 0 || props[0].ToLower() != "native")
			{
				return new Error[]{new Error(file, "This file must have svn:eol-style set to native")};
			}

			return Error.NoErrors;
		}
		public Error[] PreCommit(RepositoryFile file)
		{
			// Check files that have the proper extension
			// but skip the files that are deleted
			if (file.ContentsStatus == RepositoryStatus.Deleted ||
				Array.IndexOf(extensions, file.Extension) == -1)
			{
				return Error.NoErrors;
			}

			// Skip AssemblyInfo.cs, it is a special
			// case file and should not be necessary
			// to add the header to. I think?
			if(file.FileName == "AssemblyInfo.cs")
				return Error.NoErrors;

			ArrayList errors = new ArrayList();

			using(Stream stream = file.GetContents())
			using(TextReader reader = new StreamReader(stream))
			{
				String line;
				int index = 0;
				while ((line = reader.ReadLine()) != null &&
						index < LINES.Length)
				{
					line = Trim(line);

					if (line == String.Empty)
					{
						if(index != 0)
						{
							AddError(errors, file, "Blank lines are not allowed in the Apache License 2.0 header");
						}

						continue;
					}

					if (line != LINES[index])
					{
						if(index == 0)
						{
							AddError(errors, file, "No text or code is allowed before the Apache License 2.0 header");
							continue;
						}
						AddError(errors, file, "Apache License 2.0 header has errors on line " + (index+1));
					}

					index++;
				}

				// if index is still at 0 we havent found the
				// header at all, clear the errors and add
				// that as error.
				if(index == 0)
				{
					errors.Clear();
					AddError(errors, file, "Apache License 2.0 header is missing or there are errors on the first line");
				}
			}

			return (Error[])errors.ToArray(typeof(Error));
		}
		private static void AddError(IList errors, RepositoryFile file, String description)
		{
			Error error = new Error(file, description);
			if (!errors.Contains(error))
				errors.Add(error);
		}
 public Error(RepositoryFile file, String description)
 {
     this.file        = file;
     this.description = description;
 }
Exemple #12
0
		[Test] public void FileNameUnderRoot()
		{
			RepositoryFile file = new RepositoryFile(repository, "/file.txt", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("file.txt", file.FileName, "RepositoryFile.FileName is not set correctly");
		}
Exemple #13
0
		[Test] public void ConstructedWithDirectoryPath()
		{
			RepositoryFile file = new RepositoryFile(repository, "trunk/", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #14
0
		[Test] public void TextSlashMimeSet()
		{
			RepositoryFile file = new RepositoryFile(repository, TEXT_SLASH_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.IsTrue(file.IsText, "RepositoryFile.IsText does not return true when svn:mime-type is set to only \"text/\"");
		}
Exemple #15
0
		[SetUp] public void SetUp()
		{
			count = 0; // this line has to be before the RepositoryFile line
			file = new RepositoryFile(this, "file", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #16
0
		[Test] public void ConstructedWithEmptyPath()
		{
			RepositoryFile file = new RepositoryFile(repository, String.Empty, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #17
0
		public Error(RepositoryFile file, String description)
		{
			this.file = file;
			this.description = description;
		}
Exemple #18
0
		[Test] public void Extension()
		{
			RepositoryFile file = new RepositoryFile(repository, "file.extension", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("extension", file.Extension, "RepositoryFile.Extension is not set properly");
		}
Exemple #19
0
		[Test] public void ExtensionNonExistantWithTrailingDot()
		{
			RepositoryFile file = new RepositoryFile(repository, "file.", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual(String.Empty, file.Extension, "RepositoryFile.Extension is not String.Empty when file does not have an extension");
		}
Exemple #20
0
		[Test] public void FileNameUnderRootWithLeadingSpaces()
		{
			RepositoryFile file = new RepositoryFile(repository, " file", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #21
0
		[Test] public void FileNameWithTrailingSpaces()
		{
			RepositoryFile file = new RepositoryFile(repository, "trunk/file ", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #22
0
		[Test] public void FileNameWithExtension()
		{
			RepositoryFile file = new RepositoryFile(repository, "file.ext", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("file.ext", file.FileName, "RepositoryFile.FileName is not set correctly");
		}
Exemple #23
0
		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;
			}
		}
Exemple #24
0
		/// <summary>
		/// This test is to counter a bug in SetPathRelatedFields
		/// in RepositoryFile, it used path.IndexOf rather than
		/// filename when gathering the extension, which broke
		/// on real paths.
		/// </summary>
		[Test] public void LongPathWithExtension()
		{
			RepositoryFile file = new RepositoryFile(repository, "trunk/Castle/File.cs", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("cs", file.Extension, "RepositoryFile.Extension is not set properly");
		}
Exemple #25
0
		/// <summary>
		/// This test ensures that a mime type beginning
		/// with "text" but not having a slash after text
		/// does not register as a text file;
		/// Subversion only considers a file a text
		/// file if it begins with "text/".
		/// </summary>
		[Test] public void TextingMimeSet()
		{
			RepositoryFile file = new RepositoryFile(repository, TEXTING_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.IsFalse(file.IsText, "RepositoryFile.IsText does not return false when svn:mime-type begins with only \"text\"");

		}
Exemple #26
0
		[Test] public void ConstructedWithNullPath()
		{
			RepositoryFile file = new RepositoryFile(repository, null, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #27
0
		[Test] public new void ToString()
		{
			RepositoryFile file = new RepositoryFile(repository, "trunk/Castle/file.txt", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("trunk/Castle/file.txt", file.ToString(), "RepositoryFile.ToString does not return the path");
		}
Exemple #28
0
		[Test] public void ConstructedWithBlankPath()
		{
			RepositoryFile file = new RepositoryFile(repository, "  ", RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);
		}
Exemple #29
0
		[Test] public void BinaryMimeSet()
		{
			RepositoryFile file = new RepositoryFile(repository, BINARY_PATH, RepositoryStatus.Unchanged, RepositoryStatus.Unchanged);

			Assert.AreEqual("application/octet-stream", file.MimeType, "RepositoryFile.MimeType does not return the svn:mime-type");
			Assert.IsFalse(file.IsText, "RepositoryFile.IsText does not return false when svn:mime-type does NOT start with \"text/\"");

		}
Exemple #30
0
        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);
            }
        }