private static void DeleteFileSystemInfo(FileSystemInfoBase fileSystemInfo, bool ignoreErrors) { if (!fileSystemInfo.Exists) { return; } try { fileSystemInfo.Attributes = FileAttributes.Normal; } catch { if (!ignoreErrors) throw; } var directoryInfo = fileSystemInfo as DirectoryInfoBase; if (directoryInfo != null) { DeleteDirectoryContentsSafe(directoryInfo, ignoreErrors); } DoSafeAction(fileSystemInfo.Delete, ignoreErrors); }
public MarkdownNode(FileSystemInfoBase location, string relativePathFromRoot, XElement markdownContent) { this.OriginalLocation = location; this.OriginalLocationUrl = location.ToUri(); this.RelativePathFromRoot = relativePathFromRoot; this.MarkdownContent = markdownContent; }
protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath) { // We don't support getting a file from the zip controller // Conceivably, it could be a zip file containing just the one file, but that's rarely interesting HttpResponseMessage notFoundResponse = Request.CreateResponse(HttpStatusCode.NotFound); return Task.FromResult(notFoundResponse); }
public INode Create(FileSystemInfoBase root, FileSystemInfoBase location) { string relativePathFromRoot = root == null ? @".\" : PathExtensions.MakeRelativePath(root, location, this.fileSystem); var directory = location as DirectoryInfoBase; if (directory != null) { return new FolderNode(directory, relativePathFromRoot); } var file = location as FileInfoBase; if (this.relevantFileDetector.IsFeatureFile(file)) { Feature feature = this.featureParser.Parse(file.FullName); if (feature != null) { return new FeatureNode(file, relativePathFromRoot, feature); } throw new InvalidOperationException("This feature file could not be read and will be excluded"); } else if (this.relevantFileDetector.IsMarkdownFile(file)) { XElement markdownContent = this.htmlMarkdownFormatter.Format(this.fileSystem.File.ReadAllText(file.FullName)); return new MarkdownNode(file, relativePathFromRoot, markdownContent); } else if (this.relevantFileDetector.IsImageFile(file)) { return new ImageNode(file, relativePathFromRoot); } throw new InvalidOperationException("Cannot create an IItemNode-derived object for " + file.FullName); }
public FeatureNode(FileSystemInfoBase location, string relativePathFromRoot, Feature feature) { this.OriginalLocation = location; this.OriginalLocationUrl = location.ToUri(); this.RelativePathFromRoot = relativePathFromRoot; this.Feature = feature; }
public static string MakeRelativePath(FileSystemInfoBase from, FileSystemInfoBase to, IFileSystem fileSystem) { if (from == null) throw new ArgumentNullException("from"); if (to == null) throw new ArgumentNullException("to"); return MakeRelativePath(from.FullName, to.FullName, fileSystem); }
/// <summary> /// Extracts a snippet. /// </summary> /// <param name="fileSystemInfo">The file system info.</param> /// <param name="pattern">The extraction pattern.</param> /// <returns>The extracted snippet.</returns> public Snippet Extract(FileSystemInfoBase fileSystemInfo, string pattern) { // Get the directory DirectoryInfoBase directoryInfo = this.ConvertToDirectory(fileSystemInfo); // Use * as pattern when none is set if (string.IsNullOrWhiteSpace(pattern)) { pattern = "*"; } try { // Search file system info from pattern FileSystemInfoBase[] fileSystemInfoBase = pattern .Split(new char[] { '|', ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => x.Trim()) .Where(x => !string.IsNullOrWhiteSpace(x)) .SelectMany(x => directoryInfo.GetFileSystemInfos(x, SearchOption.AllDirectories)) .OrderByDescending(x => x is DirectoryInfoBase) .ThenBy(x => x.FullName) .ToArray(); // Build snippet return this.BuildSnippet(directoryInfo, fileSystemInfoBase); } // Rethrow a snippet extraction exception if the directory is not found catch (DirectoryNotFoundException) { throw new SnippetExtractionException("Cannot find directory", pattern); } }
internal static string GetDestinationPath(string sourceRootPath, string destinationRootPath, FileSystemInfoBase info) { string sourcePath = info.FullName; sourcePath = sourcePath.Substring(sourceRootPath.Length) .Trim(Path.DirectorySeparatorChar); return Path.Combine(destinationRootPath, sourcePath); }
public static ItemType GetItemType(FileSystemInfoBase itemInfo) { if(itemInfo is FileInfoBase) { return ItemType.File; } if (itemInfo is DirectoryInfoBase) { return ItemType.Directory; } throw new NotImplementedException(); }
/// <summary> /// Converts a FileSystemInfo to DirectoryInfo. /// </summary> /// <param name="fileSystemInfo">The file system info.</param> /// <returns>The directory info.</returns> protected DirectoryInfoBase ConvertToDirectory(FileSystemInfoBase fileSystemInfo) { // Data validation Ensure.That(() => fileSystemInfo).IsNotNull(); // Cast to DirectoryInfo DirectoryInfoBase directoryInfo = fileSystemInfo as DirectoryInfoBase; Ensure.That(() => directoryInfo).IsNotNull(); // Return as directory return directoryInfo; }
/// <summary> /// Extracts a snippet. /// </summary> /// <param name="fileSystemInfo">The file system info.</param> /// <param name="pattern">The extraction pattern, never used for this implementation.</param> /// <returns>The extracted snippet.</returns> public virtual Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string pattern) { // Data validation if (null == fileSystemInfo) throw new ArgumentNullException("fileSystemInfo"); // Extract file content string sourceCode = this.LoadFile(this.ConvertToFile(fileSystemInfo)); // Return the entire code return new Model.PlainTextSnippet(sourceCode); }
public FileSystemCabinetItemInfo(FileSystemInfoBase itemInfo, string baseDirectory) { if (itemInfo == null) throw new ArgumentNullException(nameof(itemInfo)); if (String.IsNullOrWhiteSpace(baseDirectory)) throw new ArgumentNullException(nameof(baseDirectory)); this.Type = GetItemType(itemInfo); this.Key = GetItemKey(itemInfo, baseDirectory); this.Exists = itemInfo.Exists; bool isExistingFile = itemInfo.Exists && this.Type == ItemType.File; var fileInfo = itemInfo as FileInfoBase; this.Size = isExistingFile ? fileInfo?.Length : null; this.LastModifiedUtc = isExistingFile ? fileInfo?.LastWriteTimeUtc : null; }
/// <summary> /// Converts a FileSystemInfo to FileInfo. /// </summary> /// <param name="fileSystemInfo">The file system info.</param> /// <returns>The file info.</returns> protected FileInfoBase ConvertToFile(FileSystemInfoBase fileSystemInfo) { // Data validation if (null == fileSystemInfo) throw new ArgumentNullException("fileSystemInfo"); // Cast to FileInfo FileInfoBase fileInfo = fileSystemInfo as FileInfoBase; if (null == fileInfo) throw new ArgumentException("fileInfo"); // Return as file return fileInfo; }
/// <summary> /// Extracts a snippet from a given rule pattern. /// </summary> /// <param name="fileSystemInfo">The file system info.</param> /// <param name="memberPattern">The member pattern to extract.</param> /// <returns>The extracted snippet.</returns> public override Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string memberPattern) { // Return the entire code if no member is specified if (string.IsNullOrWhiteSpace(memberPattern)) { return base.Extract(fileSystemInfo, memberPattern); } // Parse the matching rule from the pattern CSharpMatchingRule rule = CSharpMatchingRule.Parse(memberPattern); // Load the trie for pattern matching if (null == this.syntaxTrie) { // Load file content string sourceCode = base.LoadFile(this.ConvertToFile(fileSystemInfo)); // Build a syntax tree from the source code SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode); SyntaxNode root = tree.GetRoot(); // Visit the syntax tree for generating a Trie for pattern matching CSharpSyntaxWalkerMatchingBuilder syntaxMatchingBuilder = new CSharpSyntaxWalkerMatchingBuilder(); syntaxMatchingBuilder.Visit(root); // Retrieve the Trie root this.syntaxTrie = syntaxMatchingBuilder.Root; } // Match the rule from the syntax matching Trie CSharpSyntaxMatchingNode matchingTrie = syntaxTrie.Match(rule.MatchingChunks); if (null == matchingTrie) { throw new SnippetExtractionException("Cannot find member", memberPattern); } // Build a snippet for extracted syntax nodes return this.BuildSnippet(matchingTrie.MatchingSyntaxNodes, rule.ExtractionMode); }
protected abstract Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath);
protected override Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists) { // We don't support putting an individual file using the zip controller HttpResponseMessage notFoundResponse = Request.CreateResponse(HttpStatusCode.NotFound); return Task.FromResult(notFoundResponse); }
private static void DeleteFileSystemInfo(FileSystemInfoBase fileSystemInfo) { try { if (fileSystemInfo.Exists) { fileSystemInfo.Attributes = FileAttributes.Normal; } } catch { } var directoryInfo = fileSystemInfo as DirectoryInfoBase; if (directoryInfo != null) { DeleteDirectoryContentsSafe(directoryInfo); } DoSafeAction(fileSystemInfo.Delete); }
protected override async Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists) { // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo. if (_currentEtag != null) { HttpResponseMessage errorResponse; if (!PrepareBranch(itemExists, out errorResponse)) { return errorResponse; } } else { // Initialize or re-initialize repository _repository.Initialize(); } // Save file try { // Get the query parameters QueryParameters parameters = new QueryParameters(this.Request); using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists)) { try { await Request.Content.CopyToAsync(fileStream); } catch (Exception ex) { Tracer.TraceError(ex); HttpResponseMessage conflictResponse = Request.CreateErrorResponse( HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex); return conflictResponse; } } // Use to track whether our rebase applied updates from master. bool updateBranchIsUpToDate = true; // Commit to local branch bool commitResult = _repository.Commit(parameters.Message, authorName: null, emailAddress: null); if (!commitResult) { HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent); noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId); return noChangeResponse; } bool rebasing = false; if (_currentEtag != null) { try { // Only rebase if VFS branch isn't up-to-date already if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch)) { // Rebase to get updates from master while checking whether we get a conflict rebasing = true; updateBranchIsUpToDate = _repository.Rebase(MasterBranch); } // Switch content back to master _repository.UpdateRef(VfsUpdateBranch); } catch (CommandLineException commandLineException) { Tracer.TraceError(commandLineException); if (rebasing) { // The rebase resulted in a conflict. We send the conflicted version to the client so that the user // can see the conflicts and resubmit. _cleanupRebaseConflict = true; HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict); _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath)); conflictResponse.Content = new StreamContent(_readStream, BufferSize); conflictResponse.Content.Headers.ContentType = _conflictMediaType; return conflictResponse; } else { HttpResponseMessage updateErrorResponse = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmUpdate_Error, commandLineException.Message)); return updateErrorResponse; } } } // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result // in a non-conflicting merge we send back the committed version so that a client // can get the latest bits. This means we use a 200 OK response instead of a 204 response. HttpResponseMessage successFileResponse = null; if (itemExists) { if (updateBranchIsUpToDate) { successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent); } else { successFileResponse = Request.CreateResponse(HttpStatusCode.OK); _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath)); successFileResponse.Content = new StreamContent(_readStream, BufferSize); successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension); } } else { successFileResponse = Request.CreateResponse(HttpStatusCode.Created); } // Get current commit ID string currentId = _repository.CurrentId; // Deploy changes unless request indicated to not deploy if (!parameters.NoDeploy) { DeployResult result = await DeployChangesAsync(currentId); if (result != null && result.Status != DeployStatus.Success) { HttpResponseMessage deploymentErrorResponse = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText)); return deploymentErrorResponse; } } // Set updated etag for the file successFileResponse.Headers.ETag = CreateEtag(currentId); return successFileResponse; } catch (Exception ex) { Tracer.TraceError(ex); HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex); return errorResponse; } }
public static string GetUriForTargetRelativeToMe(this Uri me, FileSystemInfoBase target, string newExtension) { return target.FullName != me.LocalPath ? me.MakeRelativeUri(target.ToUri()).ToString().Replace(target.Extension, newExtension) : "#"; }
private string ShorthandAttributes(FileSystemInfoBase sourceFile) { var sb = new StringBuilder("["); var sfa = sourceFile.Attributes; if ((sfa & FileAttributes.Archive) == FileAttributes.Archive) { sb.Append("A"); } if ((sfa & FileAttributes.Hidden) == FileAttributes.Hidden) { sb.Append("H"); } if ((sfa & FileAttributes.System) == FileAttributes.System) { sb.Append("S"); } if ((sfa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { sb.Append("R"); } if ((sfa & FileAttributes.Compressed) == FileAttributes.Compressed) { sb.Append("C"); } if ((sfa & FileAttributes.Encrypted) == FileAttributes.Encrypted) { sb.Append("E"); } if (sb.Length == 1) { return String.Empty; } sb.Append("]"); return sb.ToString(); }
void CopyFileToLocation(FileSystemInfoBase target, IPackageFile x) { var targetPath = Path.Combine(target.FullName, x.EffectivePath); var fi = fileSystem.GetFileInfo(targetPath); if (fi.Exists) fi.Delete(); var dir = fileSystem.GetDirectoryInfo(Path.GetDirectoryName(targetPath)); if (!dir.Exists) dir.Create(); using (var inf = x.GetStream()) using (var of = fi.Open(FileMode.CreateNew, FileAccess.Write)) { log.Debug("Writing {0} to app directory", targetPath); inf.CopyTo(of); } }
public ImageNode(FileSystemInfoBase location, string relativePathFromRoot) { this.OriginalLocation = location; this.OriginalLocationUrl = location.ToUri(); this.RelativePathFromRoot = relativePathFromRoot; }
protected abstract Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists);
protected override async Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists) { // Check that we have a matching conditional If-Match request for existing resources if (itemExists) { // Get current etag EntityTagHeaderValue currentEtag = CreateEntityTag(info); // Existing resources require an etag to be updated. if (Request.Headers.IfMatch == null) { HttpResponseMessage missingIfMatchResponse = Request.CreateErrorResponse( HttpStatusCode.PreconditionFailed, Resources.VfsController_MissingIfMatch); return missingIfMatchResponse; } bool isMatch = false; foreach (EntityTagHeaderValue etag in Request.Headers.IfMatch) { if (currentEtag.Equals(etag) || etag == EntityTagHeaderValue.Any) { isMatch = true; break; } } if (!isMatch) { HttpResponseMessage conflictFileResponse = Request.CreateErrorResponse( HttpStatusCode.PreconditionFailed, Resources.VfsController_EtagMismatch); conflictFileResponse.Headers.ETag = currentEtag; return conflictFileResponse; } } // Save file try { using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists)) { try { await Request.Content.CopyToAsync(fileStream); } catch (Exception ex) { Tracer.TraceError(ex); HttpResponseMessage conflictResponse = Request.CreateErrorResponse( HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex); return conflictResponse; } } // Return either 204 No Content or 201 Created response HttpResponseMessage successFileResponse = Request.CreateResponse(itemExists ? HttpStatusCode.NoContent : HttpStatusCode.Created); // Set updated etag for the file info.Refresh(); successFileResponse.SetEntityTagHeader(CreateEntityTag(info), info.LastWriteTimeUtc); return successFileResponse; } catch (Exception ex) { Tracer.TraceError(ex); HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex); return errorResponse; } }
private IEnumerable<VfsStatEntry> GetDirectoryResponse(FileSystemInfoBase[] infos) { string baseAddress = Request.RequestUri.AbsoluteUri; foreach (FileSystemInfoBase fileSysInfo in infos) { bool isDirectory = (fileSysInfo.Attributes & FileAttributes.Directory) != 0; string mime = isDirectory ? _directoryMediaType.ToString() : MediaTypeMap.GetMediaType(fileSysInfo.Extension).ToString(); string unescapedHref = isDirectory ? fileSysInfo.Name + UriSegmentSeparator : fileSysInfo.Name; long size = isDirectory ? 0 : ((FileInfoBase)fileSysInfo).Length; yield return new VfsStatEntry { Name = fileSysInfo.Name, MTime = fileSysInfo.LastWriteTimeUtc, Mime = mime, Size = size, Href = baseAddress + Uri.EscapeUriString(unescapedHref), Path = fileSysInfo.FullName }; } // add special folders when requesting Root url IHttpRouteData routeData = Request.GetRouteData(); if (routeData != null && String.IsNullOrEmpty(routeData.Values["path"] as string)) { foreach (var entry in VfsSpecialFolders.GetEntries(baseAddress)) { yield return entry; } } }
/// <summary> /// Create unique etag based on the last modified UTC time /// </summary> private static EntityTagHeaderValue CreateEntityTag(FileSystemInfoBase sysInfo) { Contract.Assert(sysInfo != null); byte[] etag = BitConverter.GetBytes(sysInfo.LastWriteTimeUtc.Ticks); var result = new StringBuilder(2 + etag.Length * 2); result.Append("\""); foreach (byte b in etag) { result.AppendFormat("{0:x2}", b); } result.Append("\""); return new EntityTagHeaderValue(result.ToString()); }
protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath) { // Check whether we have a conditional If-None-Match request if (IsIfNoneMatchRequest(_currentEtag)) { HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified); notModifiedResponse.Headers.ETag = _currentEtag; return Task.FromResult(notModifiedResponse); } // Check whether we have a conditional range request containing both a Range and If-Range header field bool isRangeRequest = IsRangeRequest(_currentEtag); // Generate file response try { _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath)); MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension); HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK); if (isRangeRequest) { successFileResponse.Content = new ByteRangeStreamContent(_readStream, Request.Headers.Range, mediaType, BufferSize); } else { successFileResponse.Content = new StreamContent(_readStream, BufferSize); successFileResponse.Content.Headers.ContentType = mediaType; } // Set etag for the file successFileResponse.Headers.ETag = _currentEtag; return Task.FromResult(successFileResponse); } catch (InvalidByteRangeException invalidByteRangeException) { // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable) // including a Content-Range header with the current size. Tracer.TraceError(invalidByteRangeException); HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException); CloseReadStream(); return Task.FromResult(invalidByteRangeResponse); } catch (Exception ex) { // Could not read the file Tracer.TraceError(ex); HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex); CloseReadStream(); return Task.FromResult(errorResponse); } }
protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath) { // Get current etag EntityTagHeaderValue currentEtag = CreateEntityTag(info); DateTime lastModified = info.LastWriteTimeUtc; // Check whether we have a range request (taking If-Range condition into account) bool isRangeRequest = IsRangeRequest(currentEtag); // Check whether we have a conditional If-None-Match request // Unless it is a range request (see RFC2616 sec 14.35.2 Range Retrieval Requests) if (!isRangeRequest && IsIfNoneMatchRequest(currentEtag)) { HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified); notModifiedResponse.SetEntityTagHeader(currentEtag, lastModified); return Task.FromResult(notModifiedResponse); } // Generate file response Stream fileStream = null; try { fileStream = GetFileReadStream(localFilePath); MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension); HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK); if (isRangeRequest) { successFileResponse.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, mediaType, BufferSize); } else { successFileResponse.Content = new StreamContent(fileStream, BufferSize); successFileResponse.Content.Headers.ContentType = mediaType; } // Set etag for the file successFileResponse.SetEntityTagHeader(currentEtag, lastModified); return Task.FromResult(successFileResponse); } catch (InvalidByteRangeException invalidByteRangeException) { // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable) // including a Content-Range header with the current size. Tracer.TraceError(invalidByteRangeException); HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException); if (fileStream != null) { fileStream.Close(); } return Task.FromResult(invalidByteRangeResponse); } catch (Exception ex) { // Could not read the file Tracer.TraceError(ex); HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex); if (fileStream != null) { fileStream.Close(); } return Task.FromResult(errorResponse); } }
private bool IgnorePath(FileSystemInfoBase fileSystemInfoBase) { return (_ignoreList.Contains(fileSystemInfoBase.Name) || _wildcardIgnoreList.Any((name) => fileSystemInfoBase.Name.EndsWith(name, StringComparison.OrdinalIgnoreCase))); }
private bool IgnorePath(FileSystemInfoBase fileName) { return _ignoreList.Contains(fileName.Name); }