com.elestrago.unity.package-tools 2.0.10 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CAHNGELOG.md +16 -0
- package/Documentation~/api.md +502 -0
- package/Documentation~/manual.md +140 -0
- package/Documentation~/samples.md +73 -0
- package/Editor/Drawers/CopyEntryPropertyDrawer.cs +95 -0
- package/Editor/Drawers/CopyEntryPropertyDrawer.cs.meta +2 -0
- package/Editor/EditorConstants.cs +6 -0
- package/Editor/Inspectors/PackageManifestConfigInspector.cs +31 -0
- package/Editor/PackageManifestConfig.cs +20 -0
- package/Editor/Tools/FileTools.cs +73 -0
- package/Samples~/ClaudeSkills/unity-package-docs/SKILL.md +309 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/README.md.template +42 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/api-chunk.md.template +41 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/api-index.md.template +26 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/api.md.template +43 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/manual.md.template +57 -0
- package/Samples~/ClaudeSkills/unity-package-docs/assets/samples.md.template +56 -0
- package/Samples~/ClaudeSkills/unity-package-docs/scripts/scan_package.py +504 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/SKILL.md +309 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/README.md.template +42 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api-chunk.md.template +41 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api-index.md.template +26 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api.md.template +43 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/manual.md.template +57 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/samples.md.template +56 -0
- package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/scripts/scan_package.py +504 -0
- package/package.json +9 -4
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<!-- generated by unity-package-docs; safe to regenerate -->
|
|
2
|
+
|
|
3
|
+
# Package Tool — Samples
|
|
4
|
+
|
|
5
|
+
How the sample content in this repository uses the package. Each entry maps a sample file to the package types it exercises, so a reader can recreate the same setup against the public API.
|
|
6
|
+
|
|
7
|
+
## Sample Layout
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Assets/Example/Sample
|
|
11
|
+
├── Prefabs
|
|
12
|
+
│ └── ExamplePrefab.prefab
|
|
13
|
+
└── Scene
|
|
14
|
+
└── SampleScene.unity
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
On export, `CopySamplesToDirectory` copies this tree to `Release/Samples~/ExampleSample/`, skipping `.meta` files. The shipped sample is consumable from the Package Manager **Samples** tab on the published package.
|
|
18
|
+
|
|
19
|
+
## Sample → Package Type Mapping
|
|
20
|
+
|
|
21
|
+
### `Assets/Example/Sample/Prefabs/ExamplePrefab.prefab`
|
|
22
|
+
|
|
23
|
+
Kind: prefab
|
|
24
|
+
|
|
25
|
+
This sample asset references no scripts from the package. It exists as a structural demo (the importing user sees a working Scene/Prefab in the package's Samples tab) rather than as an API exercise.
|
|
26
|
+
|
|
27
|
+
### `Assets/Example/Sample/Scene/SampleScene.unity`
|
|
28
|
+
|
|
29
|
+
Kind: scene
|
|
30
|
+
|
|
31
|
+
This sample asset references no scripts from the package. It exists as a structural demo (the importing user sees a working Scene/Prefab in the package's Samples tab) rather than as an API exercise.
|
|
32
|
+
|
|
33
|
+
## Reproducing the Sample
|
|
34
|
+
|
|
35
|
+
The example sample is structural only — there are no MonoBehaviour scripts to instantiate. To reproduce from scratch:
|
|
36
|
+
|
|
37
|
+
1. Create an empty Unity scene and a primitive prefab; both can live anywhere in `Assets/`.
|
|
38
|
+
2. Create a `PackageManifestConfig` asset via **Assets > Create > JCMG/PackageTools/PackageManifestConfig** and configure `sourcePath`, `packageDestinationPath`, and a [`Sample`](api.md#packagemanifestconfigsample) entry whose `sourcePath` points at the folder holding the scene and prefab.
|
|
39
|
+
3. Click **Export Package Source** on the inspector — `FileTools.CreateOrUpdatePackageSource` runs the export pipeline (see `manual.md` → **Export pipeline**) and the sample folder lands under `packageDestinationPath/Samples~/{folderName}`.
|
|
40
|
+
|
|
41
|
+
Minimal equivalent in C#:
|
|
42
|
+
|
|
43
|
+
```csharp
|
|
44
|
+
using PackageTool;
|
|
45
|
+
using PackageTool.Tools;
|
|
46
|
+
using UnityEditor;
|
|
47
|
+
using UnityEngine;
|
|
48
|
+
|
|
49
|
+
var config = ScriptableObject.CreateInstance<PackageManifestConfig>();
|
|
50
|
+
config.packageName = "com.example.sample";
|
|
51
|
+
config.displayName = "Example Sample Package";
|
|
52
|
+
config.packageVersion = "1.0.0";
|
|
53
|
+
config.unityVersion = "2021.3";
|
|
54
|
+
config.sourcePath = "Assets/Example/Source";
|
|
55
|
+
config.packageDestinationPath = "Release";
|
|
56
|
+
config.samples = new[]
|
|
57
|
+
{
|
|
58
|
+
new PackageManifestConfig.Sample
|
|
59
|
+
{
|
|
60
|
+
sourcePath = "Assets/Example/Sample",
|
|
61
|
+
displayName = "Example Sample",
|
|
62
|
+
folderName = "ExampleSample",
|
|
63
|
+
description = "This is example for check test samples",
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
AssetDatabase.CreateAsset(config, "Assets/Example/PackageManifestConfig.asset");
|
|
67
|
+
FileTools.CreateOrUpdatePackageSource(config);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Notes
|
|
71
|
+
|
|
72
|
+
- The `Samples~/` folder name (trailing tilde) is a Unity convention: tilde-suffixed folders are excluded from the AssetDatabase import, so packaged samples don't pollute the consuming project until the user clicks **Import** in the Package Manager.
|
|
73
|
+
- For samples that stage content from outside `Assets/` — e.g. a Claude skill folder, vendored data, or generated output — use a [`CopyEntry`](api.md#packagemanifestconfigcopyentry) with `destinationPath` pointing at the same `sourcePath` your `Sample` declares. The `CopyEntry` step runs first; `CopySamplesToDirectory` then ships the staged content into the package.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
using PackageTool.Tools;
|
|
2
|
+
using UnityEditor;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
|
|
5
|
+
namespace PackageTool.Drawers
|
|
6
|
+
{
|
|
7
|
+
[CustomPropertyDrawer(typeof(PackageManifestConfig.CopyEntry))]
|
|
8
|
+
internal sealed class CopyEntryPropertyDrawer : PropertyDrawer
|
|
9
|
+
{
|
|
10
|
+
private const string SOURCE_PATH_PROPERTY_NAME = "sourcePath";
|
|
11
|
+
private const string DESTINATION_PATH_PROPERTY_NAME = "destinationPath";
|
|
12
|
+
|
|
13
|
+
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
|
14
|
+
{
|
|
15
|
+
var sourceRect = new Rect(position)
|
|
16
|
+
{
|
|
17
|
+
height = EditorConstants.FOLDER_PATH_PICKER_HEIGHT
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
var destinationRect = new Rect(sourceRect)
|
|
21
|
+
{
|
|
22
|
+
position = new Vector2(position.x, sourceRect.y + sourceRect.height + 2f)
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
DrawSourceRow(sourceRect, property.FindPropertyRelative(SOURCE_PATH_PROPERTY_NAME));
|
|
26
|
+
DrawDestinationRow(destinationRect, property.FindPropertyRelative(DESTINATION_PATH_PROPERTY_NAME));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
|
30
|
+
=> EditorConstants.FOLDER_PATH_PICKER_HEIGHT * 2f + 2f;
|
|
31
|
+
|
|
32
|
+
private static void DrawSourceRow(Rect rowRect, SerializedProperty pathProperty)
|
|
33
|
+
{
|
|
34
|
+
var fieldRect = new Rect(rowRect)
|
|
35
|
+
{
|
|
36
|
+
width = rowRect.width - EditorConstants.FOLDER_PATH_PICKER_HEIGHT * 2f
|
|
37
|
+
- EditorConstants.FOLDER_PATH_PICKER_BUFFER
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
EditorGUI.PropertyField(fieldRect, pathProperty, new GUIContent(EditorConstants.COPY_ENTRY_SOURCE_LABEL));
|
|
41
|
+
|
|
42
|
+
var filePickerRect = new Rect
|
|
43
|
+
{
|
|
44
|
+
position = new Vector2(
|
|
45
|
+
fieldRect.x + fieldRect.width + EditorConstants.FOLDER_PATH_PICKER_BUFFER,
|
|
46
|
+
rowRect.y),
|
|
47
|
+
width = EditorConstants.FOLDER_PATH_PICKER_HEIGHT,
|
|
48
|
+
height = EditorConstants.FOLDER_PATH_PICKER_HEIGHT
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
var folderPickerRect = new Rect
|
|
52
|
+
{
|
|
53
|
+
position = new Vector2(
|
|
54
|
+
filePickerRect.x + filePickerRect.width,
|
|
55
|
+
rowRect.y),
|
|
56
|
+
width = EditorConstants.FOLDER_PATH_PICKER_HEIGHT,
|
|
57
|
+
height = EditorConstants.FOLDER_PATH_PICKER_HEIGHT
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
GUILayoutTools.DrawFilePicker(
|
|
61
|
+
filePickerRect,
|
|
62
|
+
pathProperty,
|
|
63
|
+
EditorConstants.SELECT_SOURCE_PATH_FILE_PICKER_TITLE);
|
|
64
|
+
GUILayoutTools.DrawFolderPicker(
|
|
65
|
+
folderPickerRect,
|
|
66
|
+
pathProperty,
|
|
67
|
+
EditorConstants.SELECT_SOURCE_PATH_PICKER_FOLDER_TITLE);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private static void DrawDestinationRow(Rect rowRect, SerializedProperty pathProperty)
|
|
71
|
+
{
|
|
72
|
+
var fieldRect = new Rect(rowRect)
|
|
73
|
+
{
|
|
74
|
+
width = rowRect.width - EditorConstants.FOLDER_PATH_PICKER_HEIGHT
|
|
75
|
+
- EditorConstants.FOLDER_PATH_PICKER_BUFFER
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
EditorGUI.PropertyField(fieldRect, pathProperty, new GUIContent(EditorConstants.COPY_ENTRY_DESTINATION_LABEL));
|
|
79
|
+
|
|
80
|
+
var folderPickerRect = new Rect
|
|
81
|
+
{
|
|
82
|
+
position = new Vector2(
|
|
83
|
+
fieldRect.x + fieldRect.width + EditorConstants.FOLDER_PATH_PICKER_BUFFER,
|
|
84
|
+
rowRect.y),
|
|
85
|
+
width = EditorConstants.FOLDER_PATH_PICKER_HEIGHT,
|
|
86
|
+
height = EditorConstants.FOLDER_PATH_PICKER_HEIGHT
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
GUILayoutTools.DrawFolderPicker(
|
|
90
|
+
folderPickerRect,
|
|
91
|
+
pathProperty,
|
|
92
|
+
EditorConstants.SELECT_COPY_DESTINATION_FOLDER_PICKER_TITLE);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -108,5 +108,11 @@ namespace PackageTool
|
|
|
108
108
|
public const string SAMPLES_FOLDER_NAME = "Samples~";
|
|
109
109
|
public const string SAMPLES_HEADER_LABEL = "Samples";
|
|
110
110
|
public const string SAMPLES_ELEMENT_LABEL_FORMAT = "Sample {0}:";
|
|
111
|
+
|
|
112
|
+
public const string COPY_ENTRIES_HEADER_LABEL = "Copy Entries";
|
|
113
|
+
public const string COPY_ENTRY_ELEMENT_LABEL_FORMAT = "Copy {0}:";
|
|
114
|
+
public const string COPY_ENTRY_SOURCE_LABEL = "Source";
|
|
115
|
+
public const string COPY_ENTRY_DESTINATION_LABEL = "Destination";
|
|
116
|
+
public const string SELECT_COPY_DESTINATION_FOLDER_PICKER_TITLE = "Select Copy Destination Folder";
|
|
111
117
|
}
|
|
112
118
|
}
|
|
@@ -37,6 +37,7 @@ namespace PackageTool.Inspectors
|
|
|
37
37
|
private ReorderableList _keywordReorderableList;
|
|
38
38
|
private ReorderableList _dependenciesReorderableList;
|
|
39
39
|
private ReorderableList _samplesReorderableList;
|
|
40
|
+
private ReorderableList _copyEntriesReorderableList;
|
|
40
41
|
|
|
41
42
|
private const string SOURCE_PATH_PROPERTY_NAME = "sourcePath";
|
|
42
43
|
private const string DOCUMENTATION_PATH_PROPERTY_NAME = "documentationPath";
|
|
@@ -61,6 +62,7 @@ namespace PackageTool.Inspectors
|
|
|
61
62
|
private const string VERSION_CONSTANTS_NAMESPACE_PROPERTY_NAME = "versionConstantsNamespace";
|
|
62
63
|
private const string ID_PROPERTY_NAME = "_id";
|
|
63
64
|
private const string SAMPLES_PROPERTY_NAME = "samples";
|
|
65
|
+
private const string COPY_ENTRIES_PROPERTY_NAME = "copyEntries";
|
|
64
66
|
|
|
65
67
|
private void OnEnable()
|
|
66
68
|
{
|
|
@@ -109,6 +111,16 @@ namespace PackageTool.Inspectors
|
|
|
109
111
|
drawElementCallback = DrawSampleElement,
|
|
110
112
|
elementHeight = EditorGUIUtility.singleLineHeight * 5f
|
|
111
113
|
};
|
|
114
|
+
|
|
115
|
+
var copyEntriesProp = serializedObject.FindProperty(COPY_ENTRIES_PROPERTY_NAME);
|
|
116
|
+
_copyEntriesReorderableList = new ReorderableList(
|
|
117
|
+
serializedObject,
|
|
118
|
+
copyEntriesProp)
|
|
119
|
+
{
|
|
120
|
+
drawHeaderCallback = DrawCopyEntriesHeader,
|
|
121
|
+
drawElementCallback = DrawCopyEntryElement,
|
|
122
|
+
elementHeight = EditorConstants.FOLDER_PATH_PICKER_HEIGHT * 2f + 2f
|
|
123
|
+
};
|
|
112
124
|
}
|
|
113
125
|
|
|
114
126
|
public override void OnInspectorGUI()
|
|
@@ -203,6 +215,7 @@ namespace PackageTool.Inspectors
|
|
|
203
215
|
EditorGUILayout.Space();
|
|
204
216
|
// _sourcePathsReorderableList.DoLayoutList();
|
|
205
217
|
_excludePathsReorderableList.DoLayoutList();
|
|
218
|
+
_copyEntriesReorderableList.DoLayoutList();
|
|
206
219
|
|
|
207
220
|
// Package Source Export
|
|
208
221
|
using (new EditorGUILayout.HorizontalScope())
|
|
@@ -400,5 +413,23 @@ namespace PackageTool.Inspectors
|
|
|
400
413
|
}
|
|
401
414
|
|
|
402
415
|
#endregion
|
|
416
|
+
|
|
417
|
+
#region Copy Entries ReorderableList
|
|
418
|
+
|
|
419
|
+
private void DrawCopyEntriesHeader(Rect rect)
|
|
420
|
+
{
|
|
421
|
+
EditorGUI.LabelField(rect, EditorConstants.COPY_ENTRIES_HEADER_LABEL, EditorStyles.boldLabel);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private void DrawCopyEntryElement(Rect rect, int index, bool isActive, bool isFocused)
|
|
425
|
+
{
|
|
426
|
+
EditorGUI.PropertyField(
|
|
427
|
+
rect,
|
|
428
|
+
serializedObject.FindProperty(COPY_ENTRIES_PROPERTY_NAME).GetArrayElementAtIndex(index),
|
|
429
|
+
new GUIContent(string.Format(EditorConstants.COPY_ENTRY_ELEMENT_LABEL_FORMAT, index))
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
#endregion
|
|
403
434
|
}
|
|
404
435
|
}
|
|
@@ -82,6 +82,21 @@ namespace PackageTool
|
|
|
82
82
|
|| string.IsNullOrEmpty(folderName);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/// <summary>
|
|
86
|
+
/// Describes a copy operation that mirrors a source file or folder into a destination folder inside the
|
|
87
|
+
/// project. When the source is a folder, the same-named subfolder of the destination is replaced with the
|
|
88
|
+
/// source folder's content. When the source is a file, the same-named file inside the destination folder
|
|
89
|
+
/// is replaced. An empty or non-existent destination path falls back to the project root.
|
|
90
|
+
/// </summary>
|
|
91
|
+
[Serializable]
|
|
92
|
+
public sealed class CopyEntry
|
|
93
|
+
{
|
|
94
|
+
public string sourcePath;
|
|
95
|
+
public string destinationPath;
|
|
96
|
+
|
|
97
|
+
public bool IsEmpty() => string.IsNullOrEmpty(sourcePath);
|
|
98
|
+
}
|
|
99
|
+
|
|
85
100
|
/// <summary>
|
|
86
101
|
/// A unique id for this <see cref="PackageManifestConfig"/> instance.
|
|
87
102
|
/// </summary>
|
|
@@ -162,6 +177,11 @@ namespace PackageTool
|
|
|
162
177
|
|
|
163
178
|
public Sample[] samples;
|
|
164
179
|
|
|
180
|
+
/// <summary>
|
|
181
|
+
/// A collection of additional source-to-destination copy operations performed during export.
|
|
182
|
+
/// </summary>
|
|
183
|
+
public CopyEntry[] copyEntries;
|
|
184
|
+
|
|
165
185
|
/// <summary>
|
|
166
186
|
/// A path to the where the VersionConstants.cs file should be created/updated
|
|
167
187
|
/// </summary>
|
|
@@ -122,6 +122,7 @@ namespace PackageTool.Tools
|
|
|
122
122
|
// If its a file, copy over it and its meta file if it exists.
|
|
123
123
|
var normalizedSourcePath = Path.GetFullPath(packageManifest.sourcePath);
|
|
124
124
|
|
|
125
|
+
CopyEntriesToProject(packageManifest);
|
|
125
126
|
CopyDocumentationToDirectory(packageManifest);
|
|
126
127
|
RecursivelyCopyDirectoriesAndFiles(packageManifest, normalizedSourcePath, normalizedDestinationPath);
|
|
127
128
|
CopySamplesToDirectory(packageManifest);
|
|
@@ -192,6 +193,78 @@ namespace PackageTool.Tools
|
|
|
192
193
|
File.Copy(normalizedSourcePath, destinationPath);
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
/// <summary>
|
|
197
|
+
/// Stages each configured <see cref="PackageManifestConfig.CopyEntry"/> into the project before the
|
|
198
|
+
/// rest of the export runs. A folder source's content is merged directly into
|
|
199
|
+
/// <see cref="PackageManifestConfig.CopyEntry.destinationPath"/> (same-named files are overwritten,
|
|
200
|
+
/// unrelated files in the destination are left alone). A file source overwrites
|
|
201
|
+
/// <c>destination/{filename}</c>. A blank destination resolves to the project root; a non-blank
|
|
202
|
+
/// destination that does not yet exist is created. Missing sources log a warning and are skipped.
|
|
203
|
+
/// </summary>
|
|
204
|
+
public static void CopyEntriesToProject(PackageManifestConfig packageManifest)
|
|
205
|
+
{
|
|
206
|
+
var entries = packageManifest.copyEntries;
|
|
207
|
+
if (entries == null || entries.Length == 0)
|
|
208
|
+
return;
|
|
209
|
+
|
|
210
|
+
foreach (var entry in entries)
|
|
211
|
+
{
|
|
212
|
+
if (entry.IsEmpty())
|
|
213
|
+
continue;
|
|
214
|
+
|
|
215
|
+
var normalizedSourcePath = Path.GetFullPath(entry.sourcePath);
|
|
216
|
+
var destinationDirectory = ResolveDestinationDirectory(entry.destinationPath);
|
|
217
|
+
|
|
218
|
+
if (!Directory.Exists(destinationDirectory))
|
|
219
|
+
Directory.CreateDirectory(destinationDirectory);
|
|
220
|
+
|
|
221
|
+
if (!Directory.Exists(normalizedSourcePath) && !File.Exists(normalizedSourcePath))
|
|
222
|
+
{
|
|
223
|
+
Debug.LogWarningFormat(
|
|
224
|
+
"[Package Tools] Copy entry source [{0}] does not exist, skipping.",
|
|
225
|
+
entry.sourcePath);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (Directory.Exists(normalizedSourcePath))
|
|
230
|
+
{
|
|
231
|
+
CopyDirectoryRecursively(normalizedSourcePath, destinationDirectory);
|
|
232
|
+
}
|
|
233
|
+
else if (File.Exists(normalizedSourcePath))
|
|
234
|
+
{
|
|
235
|
+
var sourceName = Path.GetFileName(normalizedSourcePath);
|
|
236
|
+
var targetPath = Path.Combine(destinationDirectory, sourceName);
|
|
237
|
+
|
|
238
|
+
if (File.Exists(targetPath))
|
|
239
|
+
File.Delete(targetPath);
|
|
240
|
+
|
|
241
|
+
File.Copy(normalizedSourcePath, targetPath);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private static string ResolveDestinationDirectory(string rawDestinationPath)
|
|
247
|
+
{
|
|
248
|
+
if (string.IsNullOrEmpty(rawDestinationPath))
|
|
249
|
+
return EditorConstants.ProjectPath;
|
|
250
|
+
|
|
251
|
+
return Path.GetFullPath(rawDestinationPath);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private static void CopyDirectoryRecursively(string normalizedSourcePath, string normalizedDestinationPath)
|
|
255
|
+
{
|
|
256
|
+
var directoryInfo = new DirectoryInfo(normalizedSourcePath);
|
|
257
|
+
|
|
258
|
+
foreach (var sdi in directoryInfo.GetDirectories(EditorConstants.WILDCARD_FILTER, SearchOption.AllDirectories))
|
|
259
|
+
Directory.CreateDirectory(sdi.FullName.Replace(normalizedSourcePath, normalizedDestinationPath));
|
|
260
|
+
|
|
261
|
+
foreach (var fi in directoryInfo.GetFiles(EditorConstants.WILDCARD_FILTER, SearchOption.AllDirectories))
|
|
262
|
+
{
|
|
263
|
+
var newPath = fi.FullName.Replace(normalizedSourcePath, normalizedDestinationPath);
|
|
264
|
+
File.Copy(fi.FullName, newPath, overwrite: true);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
195
268
|
private static void CopySamplesToDirectory(PackageManifestConfig packageManifest)
|
|
196
269
|
{
|
|
197
270
|
var samples = packageManifest.samples;
|