/// <summary> /// Archive a file given the file contents. /// </summary> /// <param name="inputPath">The path of the file.</param> /// <param name="contents">The contents of the file.</param> public void Archive(PathTransformer.ITransformedPath inputPath, string contents) { if (string.IsNullOrEmpty(archive)) { return; } ArchiveContents(inputPath, contents); }
public static string TrapPath(ILogger logger, string?folder, PathTransformer.ITransformedPath path, TrapWriter.CompressionMode trapCompression) { var filename = $"{path.Value}.trap{TrapExtension(trapCompression)}"; if (string.IsNullOrEmpty(folder)) { folder = Directory.GetCurrentDirectory(); } return(NestPaths(logger, folder, filename)); }
/// <summary> /// Finds the suitable directories for a given source file. /// Returns null if not included in the layout. /// </summary> /// <param name="sourceFile">The file to look up.</param> /// <returns>The relevant subproject, or null if not found.</returns> public SubProject?LookupProjectOrNull(PathTransformer.ITransformedPath sourceFile) { if (!useLayoutFile) { return(defaultProject); } return(blocks .Where(block => block.Matches(sourceFile)) .Select(block => block.Directories) .FirstOrDefault()); }
public TrapWriter(ILogger logger, PathTransformer.ITransformedPath outputfile, string?trap, string?archive, CompressionMode trapCompression, bool discardDuplicates) { this.logger = logger; this.trapCompression = trapCompression; TrapFile = TrapPath(this.logger, trap, outputfile, trapCompression); writerLazy = new Lazy <StreamWriter>(() => { var tempPath = trap ?? Path.GetTempPath(); do { /* * Write the trap to a random filename in the trap folder. * Since the trap path can be very long, we need to deal with the possibility of * PathTooLongExceptions. So we use a short filename in the trap folder, * then move it later. * * Although GetRandomFileName() is cryptographically secure, * there's a tiny chance the file could already exists. */ tmpFile = Path.Combine(tempPath, Path.GetRandomFileName()); }while (File.Exists(tmpFile)); var fileStream = new FileStream(tmpFile, FileMode.CreateNew, FileAccess.Write); Stream compressionStream; switch (trapCompression) { case CompressionMode.Brotli: compressionStream = new BrotliStream(fileStream, CompressionLevel.Fastest); break; case CompressionMode.Gzip: compressionStream = new GZipStream(fileStream, CompressionLevel.Fastest); break; case CompressionMode.None: compressionStream = fileStream; break; default: throw new ArgumentOutOfRangeException(nameof(trapCompression), trapCompression, "Unsupported compression type"); } return(new StreamWriter(compressionStream, utf8, 2000000)); }); this.archive = archive; this.discardDuplicates = discardDuplicates; }
private string tmpFile = ""; // The temporary file which is moved to trapFile once written. /// <summary> /// Adds the specified input file to the source archive. It may end up in either the normal or long path area /// of the source archive, depending on the length of its full path. /// </summary> /// <param name="originalPath">The path to the input file.</param> /// <param name="transformedPath">The transformed path to the input file.</param> /// <param name="inputEncoding">The encoding used by the input file.</param> public void Archive(string originalPath, PathTransformer.ITransformedPath transformedPath, Encoding inputEncoding) { if (string.IsNullOrEmpty(archive)) { return; } // Calling GetFullPath makes this use the canonical capitalisation, if the file exists. var fullInputPath = Path.GetFullPath(originalPath); ArchivePath(fullInputPath, transformedPath, inputEncoding); }
private void ArchiveContents(PathTransformer.ITransformedPath transformedPath, string contents) { var dest = NestPaths(logger, archive, transformedPath.Value); var tmpSrcFile = Path.GetTempFileName(); File.WriteAllText(tmpSrcFile, contents, utf8); try { FileUtils.MoveOrReplace(tmpSrcFile, dest); } catch (IOException ex) { // If this happened, it was probably because the same file was compiled multiple times. // In any case, this is not a fatal error. logger.Log(Severity.Warning, "Problem archiving " + dest + ": " + ex); } }
public File(Context cx, string path) : base(cx) { this.OriginalPath = path; TransformedPath = Context.Extractor.PathTransformer.Transform(OriginalPath); }
/// <summary> /// Creates a folder entitiy with the given path. /// </summary> /// <param name="path">The path of the folder.</param> /// <returns>A folder entity.</returns> public Folder CreateFolder(PathTransformer.ITransformedPath path) => folders[path];
public Folder(Context cx, PathTransformer.ITransformedPath path) : base(cx) { this.transformedPath = path; }
/// <summary> /// Finds the suitable directories for a given source file. /// Returns the default project if not included in the layout. /// </summary> /// <param name="sourceFile">The file to look up.</param> /// <returns>The relevant subproject, or DefaultProject if not found.</returns> public SubProject LookupProjectOrDefault(PathTransformer.ITransformedPath sourceFile) { return(LookupProjectOrNull(sourceFile) ?? defaultProject); }
/// <summary> /// Creates a trap writer for a given source/assembly file. /// </summary> /// <param name="srcFile">The source file.</param> /// <returns>A newly created TrapWriter.</returns> public TrapWriter CreateTrapWriter(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression, bool discardDuplicates) => new TrapWriter(logger, srcFile, TRAP_FOLDER, SOURCE_ARCHIVE, trapCompression, discardDuplicates);
/// <summary> /// Gets the name of the trap file for a given source/assembly file. /// </summary> /// <param name="srcFile">The source file.</param> /// <returns>The full filepath of the trap file.</returns> public string GetTrapPath(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression) => TrapWriter.TrapPath(logger, TRAP_FOLDER, srcFile, trapCompression);
public bool Matches(PathTransformer.ITransformedPath path) => FilePattern.Matches(filePatterns, path.Value, out var _);
/// <summary> /// Is the source file included in the layout? /// </summary> /// <param name="path">The absolute path of the file to query.</param> /// <returns>True iff there is no layout file or the layout file specifies the file.</returns> public bool FileInLayout(PathTransformer.ITransformedPath path) => LookupProjectOrNull(path) != null;
/// <summary> /// Attempts to archive the specified input file to the normal area of the source archive. /// The file's path must be sufficiently short so as to render the path of its copy in the /// source archive less than the system path limit of 260 characters. /// </summary> /// <param name="fullInputPath">The full path to the input file.</param> /// <param name="transformedPath">The transformed path to the input file.</param> /// <param name="inputEncoding">The encoding used by the input file.</param> /// <exception cref="PathTooLongException">If the output path in the source archive would /// exceed the system path limit of 260 characters.</exception> private void ArchivePath(string fullInputPath, PathTransformer.ITransformedPath transformedPath, Encoding inputEncoding) { var contents = File.ReadAllText(fullInputPath, inputEncoding); ArchiveContents(transformedPath, contents); }