/// <summary> /// Creates manifest nodes for a set of file system elements. /// </summary> /// <param name="entries">The file system elements to create nodes for.</param> /// <returns>The nodes for the elements.</returns> private IEnumerable <ManifestNode> GetNodes(IEnumerable <FileSystemInfo> entries) { var externalXbits = FlagUtils.GetFiles(FlagUtils.XbitFile, TargetDir); var externalSymlinks = FlagUtils.GetFiles(FlagUtils.SymlinkFile, TargetDir); // Iterate through the directory listing to build a list of manifets entries var nodes = new List <ManifestNode>(); foreach (var entry in entries) { CancellationToken.ThrowIfCancellationRequested(); var file = entry as FileInfo; if (file != null) { // Don't include manifest management files in manifest if (file.Name == Manifest.ManifestFile || file.Name == FlagUtils.XbitFile || file.Name == FlagUtils.SymlinkFile) { continue; } nodes.Add(GetFileNode(file, Format, externalXbits, externalSymlinks)); UnitsProcessed += file.Length; } else { var directory = entry as DirectoryInfo; if (directory != null) { nodes.Add(GetDirectoryNode(directory, Format, Path.GetFullPath(TargetDir))); } } } return(nodes); }
public void TestApplyRecipeArchiv() { using (var archiveFile = new TemporaryFile("0install-unit-tests")) { typeof(ExtractorTest).WriteEmbeddedFile("testArchive.zip", archiveFile); var downloadedFiles = new[] { archiveFile }; var recipe = new Recipe { Steps = { new Archive { MimeType = Archive.MimeTypeZip, Destination = "subDir" } } }; using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler())) { // /dest/symlink [S] string path = new[] { recipeDir, "subDir", "symlink" }.Aggregate(Path.Combine); Assert.IsTrue(File.Exists(path), "File should exist: " + path); if (!UnixUtils.IsUnix) { CollectionAssert.AreEquivalent(new[] { path }, FlagUtils.GetFiles(FlagUtils.SymlinkFile, recipeDir)); } // /dest/subdir2/executable [deleted] path = new[] { recipeDir, "subDir", "subdir2", "executable" }.Aggregate(Path.Combine); Assert.IsTrue(File.Exists(path), "File should exist: " + path); if (!UnixUtils.IsUnix) { CollectionAssert.AreEquivalent(new[] { path }, FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir)); } } } }
public void TestApplyRecipeSingleFile() { using (var singleFile = new TemporaryFile("0install-unit-tests")) using (var archiveFile = new TemporaryFile("0install-unit-tests")) { File.WriteAllText(singleFile, "data"); typeof(ArchiveExtractorTest).CopyEmbeddedToFile("testArchive.zip", archiveFile); var downloadedFiles = new[] { archiveFile, singleFile }; var recipe = new Recipe { Steps = { new Archive { MimeType = Archive.MimeTypeZip }, new SingleFile{ Destination = "subdir2/executable" } } }; using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler())) { // /subdir2/executable [!X] string path = Path.Combine(recipeDir, "subdir2", "executable"); File.Exists(path).Should().BeTrue(because: "File should exist: " + path); File.ReadAllText(path).Should().Be("data"); File.GetLastWriteTimeUtc(path).ToUnixTime() .Should().Be(0, because: "Single files should be set to Unix epoch"); if (!UnixUtils.IsUnix) { FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir).Should().BeEmpty(); } } } }
public void TestGetFiles() { using (var flagDir = new TemporaryDirectory("0install-unit-tests")) { File.WriteAllText(Path.Combine(flagDir, FlagUtils.XbitFile), "/dir1/file1\n/dir2/file2\n"); var expectedResult = new[] { new[] { flagDir, "dir1", "file1" }.Aggregate(Path.Combine), new[] { flagDir, "dir2", "file2" }.Aggregate(Path.Combine) }; CollectionAssert.AreEquivalent(expectedResult, FlagUtils.GetFiles(FlagUtils.XbitFile, flagDir), "Should find .xbit file in same directory"); CollectionAssert.AreEquivalent(expectedResult, FlagUtils.GetFiles(FlagUtils.XbitFile, Path.Combine(flagDir, "subdir")), "Should find .xbit file in parent directory"); } }
public void TestGetFiles() { using (var flagDir = new TemporaryDirectory("0install-unit-tests")) { File.WriteAllText(Path.Combine(flagDir, FlagUtils.XbitFile), "/dir1/file1\n/dir2/file2\n"); var expectedResult = new[] { Path.Combine(flagDir, "dir1", "file1"), Path.Combine(flagDir, "dir2", "file2") }; FlagUtils.GetFiles(FlagUtils.XbitFile, flagDir) .Should().BeEquivalentTo(expectedResult, because: "Should find .xbit file in same directory"); FlagUtils.GetFiles(FlagUtils.XbitFile, Path.Combine(flagDir, "subdir")) .Should().BeEquivalentTo(expectedResult, because: "Should find .xbit file in parent directory"); } }
public void TestApplyRecipeRemove() { using (var archiveFile = new TemporaryFile("0install-unit-tests")) { typeof(ArchiveExtractorTest).CopyEmbeddedToFile("testArchive.zip", archiveFile); var downloadedFiles = new[] { archiveFile }; var recipe = new Recipe { Steps = { new Archive { MimeType = Archive.MimeTypeZip }, new RemoveStep { Path = "symlink" }, new RemoveStep { Path = "subdir2" } } }; using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler())) { if (!UnixUtils.IsUnix) { FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir).Should().BeEmpty(); FlagUtils.GetFiles(FlagUtils.SymlinkFile, recipeDir).Should().BeEmpty(); } // /symlink [deleted] string path = Path.Combine(recipeDir, "symlink"); File.Exists(path).Should().BeFalse(because: "File should not exist: " + path); // /subdir2 [deleted] path = Path.Combine(recipeDir, "subdir2"); Directory.Exists(path).Should().BeFalse(because: "Directory should not exist: " + path); } } }
public void TestApplyRecipeArchiv() { using (var archiveFile = new TemporaryFile("0install-unit-tests")) { typeof(ArchiveExtractorTest).CopyEmbeddedToFile("testArchive.zip", archiveFile); var downloadedFiles = new[] { archiveFile }; var recipe = new Recipe { Steps = { new Archive { MimeType = Archive.MimeTypeZip, Destination = "subDir" } } }; using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler())) { // /dest/symlink [S] string path = Path.Combine(recipeDir, "subDir", "symlink"); File.Exists(path).Should().BeTrue(because: "File should exist: " + path); if (UnixUtils.IsUnix) { FileUtils.IsSymlink(path).Should().BeTrue(); } else { CygwinUtils.IsSymlink(path).Should().BeTrue(); } // /dest/subdir2/executable [deleted] path = Path.Combine(recipeDir, "subDir", "subdir2", "executable"); File.Exists(path).Should().BeTrue(because: "File should exist: " + path); if (!UnixUtils.IsUnix) { FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir).Should().BeEquivalentTo(path); } } } }
/// <summary> /// Iterates over all <paramref name="entries"/> and calls handler methods for them. /// </summary> /// <exception cref="NotSupportedException">A file has illegal properties (e.g. is a device file, has line breaks in the filename, etc.).</exception> /// <exception cref="IOException">There was an error reading a file.</exception> /// <exception cref="UnauthorizedAccessException">You have insufficient rights to read a file.</exception> protected virtual void HandleEntries([NotNull] IEnumerable <FileSystemInfo> entries) { #region Sanity checks if (entries == null) { throw new ArgumentNullException(nameof(entries)); } #endregion var externalXbits = FlagUtils.GetFiles(FlagUtils.XbitFile, SourceDirectory.FullName); var externalSymlinks = FlagUtils.GetFiles(FlagUtils.SymlinkFile, SourceDirectory.FullName); foreach (var entry in entries) { CancellationToken.ThrowIfCancellationRequested(); var file = entry as FileInfo; if (file != null) { if (file.Name == Manifest.ManifestFile || file.Name == FlagUtils.XbitFile || file.Name == FlagUtils.SymlinkFile) { continue; } HandleEntry(file, externalXbits, externalSymlinks); UnitsProcessed += file.Length; } else { var directory = entry as DirectoryInfo; if (directory != null) { HandleEntry(directory); } } } }
public void TestApplyRecipeRename() { using (var archiveFile = new TemporaryFile("0install-unit-tests")) { typeof(ExtractorTest).WriteEmbeddedFile("testArchive.zip", archiveFile); var downloadedFiles = new[] { archiveFile }; var recipe = new Recipe { Steps = { new Archive { MimeType = Archive.MimeTypeZip }, new RenameStep { Source = "symlink", Destination = "subdir3/symlink2" }, new RenameStep { Source = "subdir2/executable", Destination = "subdir2/executable2" } } }; using (TemporaryDirectory recipeDir = recipe.Apply(downloadedFiles, new SilentTaskHandler())) { if (!UnixUtils.IsUnix) { CollectionAssert.AreEquivalent( new[] { new[] { recipeDir, "subdir2", "executable2" }.Aggregate(Path.Combine) }, FlagUtils.GetFiles(FlagUtils.XbitFile, recipeDir)); CollectionAssert.AreEquivalent( new[] { new[] { recipeDir, "subdir3", "symlink2" }.Aggregate(Path.Combine) }, FlagUtils.GetFiles(FlagUtils.SymlinkFile, recipeDir)); } // /symlink [deleted] string path = Path.Combine(recipeDir, "symlink"); Assert.IsFalse(File.Exists(path), "File should not exist: " + path); // /subdir3/symlink2 [S] path = new[] { recipeDir, "subdir3", "symlink2" }.Aggregate(Path.Combine); Assert.IsTrue(File.Exists(path), "Missing file: " + path); if (UnixUtils.IsUnix) { Assert.IsTrue(FileUtils.IsSymlink(path), "Not symlink: " + path); } // /subdir2/executable [deleted] path = new[] { recipeDir, "subdir2", "executable" }.Aggregate(Path.Combine); Assert.IsFalse(File.Exists(path), "File should not exist: " + path); // /subdir2/executable2 [X] path = new[] { recipeDir, "subdir2", "executable2" }.Aggregate(Path.Combine); Assert.IsTrue(File.Exists(path), "Missing file: " + path); if (UnixUtils.IsUnix) { Assert.IsTrue(FileUtils.IsExecutable(path), "Not executable: " + path); } } } }