-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathPackageFolderReader.cs
146 lines (122 loc) · 4.97 KB
/
PackageFolderReader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using NuGet.Frameworks;
namespace NuGet.Packaging
{
/// <summary>
/// Reads an unzipped nupkg folder.
/// </summary>
public class PackageFolderReader : PackageReaderBase
{
private readonly DirectoryInfo _root;
/// <summary>
/// Package folder reader
/// </summary>
public PackageFolderReader(string folderPath)
: this(folderPath, DefaultFrameworkNameProvider.Instance, DefaultCompatibilityProvider.Instance)
{
}
/// <summary>
/// Package folder reader
/// </summary>
/// <param name="folder">root directory of an extracted nupkg</param>
public PackageFolderReader(DirectoryInfo folder)
: this(folder, DefaultFrameworkNameProvider.Instance, DefaultCompatibilityProvider.Instance)
{
}
/// <summary>
/// Package folder reader
/// </summary>
/// <param name="folderPath">root directory of an extracted nupkg</param>
/// <param name="frameworkProvider">framework mappings</param>
/// <param name="compatibilityProvider">framework compatibility provider</param>
public PackageFolderReader(string folderPath, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
: this(new DirectoryInfo(folderPath), frameworkProvider, compatibilityProvider)
{
}
/// <summary>
/// Package folder reader
/// </summary>
/// <param name="folder">root directory of an extracted nupkg</param>
/// <param name="frameworkProvider">framework mappings</param>
/// <param name="compatibilityProvider">framework compatibility provider</param>
public PackageFolderReader(DirectoryInfo folder, IFrameworkNameProvider frameworkProvider, IFrameworkCompatibilityProvider compatibilityProvider)
: base(frameworkProvider, compatibilityProvider)
{
_root = folder;
}
/// <summary>
/// Opens the nuspec file in read only mode.
/// </summary>
public override Stream GetNuspec()
{
var nuspecFile = _root.GetFiles("*.nuspec", SearchOption.TopDirectoryOnly).FirstOrDefault();
if (nuspecFile == null)
{
throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Strings.MissingNuspec, _root.FullName));
}
return nuspecFile.OpenRead();
}
/// <summary>
/// Opens a local file in read only mode.
/// </summary>
public override Stream GetStream(string path)
{
var file = new FileInfo(Path.Combine(_root.FullName, path));
if (!file.FullName.StartsWith(_root.FullName, StringComparison.OrdinalIgnoreCase))
{
// the given path does not appear under the folder root
throw new FileNotFoundException(path);
}
return file.OpenRead();
}
public override IEnumerable<string> GetFiles()
{
var searchFolder = new DirectoryInfo(_root.FullName);
foreach (var file in searchFolder.GetFiles("*", SearchOption.AllDirectories))
{
yield return GetRelativePath(_root, file);
}
yield break;
}
// TODO: add support for NuGet.ContentModel here
protected override IEnumerable<string> GetFiles(string folder)
{
var searchFolder = new DirectoryInfo(Path.Combine(_root.FullName, folder));
if (searchFolder.Exists)
{
foreach (var file in searchFolder.GetFiles("*", SearchOption.AllDirectories))
{
yield return GetRelativePath(_root, file);
}
}
yield break;
}
/// <summary>
/// Build the relative path in the same format that ZipArchive uses
/// </summary>
private static string GetRelativePath(DirectoryInfo root, FileInfo file)
{
var parents = new Stack<DirectoryInfo>();
var parent = file.Directory;
while (parent != null
&& !StringComparer.OrdinalIgnoreCase.Equals(parent.FullName, root.FullName))
{
parents.Push(parent);
parent = parent.Parent;
}
if (parent == null)
{
// the given file path does not appear under root
throw new FileNotFoundException(file.FullName);
}
var parts = parents.Select(d => d.Name).Concat(new string[] { file.Name });
return String.Join("/", parts);
}
}
}