Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add documentation explaining the Directory structure #687

Merged
merged 2 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 61 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ Click the **Update** (or **Downgrade**) button to uninstall the current package

# How does NuGetForUnity work?

NuGetForUnity loads the _NuGet.config_ file in the Unity project (automatically created if there isn't already one) in order to determine the server it should pull packages down from and push packages up to. By default, this server is set to the nuget.org package source.
NuGetForUnity loads the _NuGet.config_ file in the Unity project (automatically created if there isn't already one) in order to determine the server it should pull packages down from and push packages up to. By default, this server is set to the `nuget.org` package source.

_The default NuGet.config file:_
<details>
<summary>The default NuGet.config file:</summary>

```xml
<?xml version="1.0" encoding="utf-8" ?>
Expand All @@ -143,29 +144,80 @@ _The default NuGet.config file:_
</configuration>
```

You can change this to any other NuGet server (such as NuGet.Server or ProGet - see below). The **NuGet → Reload NuGet.config** menu item is useful if you are editing the _NuGet.config_ file.
</details></br>

See more information about _NuGet.config_ files here: [https://docs.nuget.org/consume/nuget-config-settings](https://docs.nuget.org/consume/nuget-config-settings)
You can change this to any other NuGet server (such as NuGet.Server or ProGet - see below). The **NuGet → Restore Packages** menu item is useful if you edited the _NuGet.config_ file. See more information about _NuGet.config_ files here: [https://docs.nuget.org/consume/nuget-config-settings](https://docs.nuget.org/consume/nuget-config-settings)

<img alt="Menu Items" src="docs/screenshots/menu_item.png" height="170px" />
## Directory structure (placement of configuration files and installed packages)

NuGetForUnity supports two different folder structures for defining where the configuration files _NuGet.config_, _packages.config_, and the downloaded `*.dll` files of the NuGet packages are stored. The placement can be changed in the `NuGet For Unity` settings UI.

### Custom within Assets

The _NuGet.config_ file will be placed in `<Unity Project Location>/Assets`, and the placement of the _packages.config_ file and the installed packages can be changed using configuration variables inside the _NuGet.config_ file. The path where NuGetForUnity installs packages, the local repository path, is defined in the _NuGet.config_ file (`repositoryPath`). By default, this is set to the `Assets/Packages` folder. The configured path can either be a full path or a relative path based on the project's Assets folder. Note: You'll probably want your Packages folder to be ignored by your version control software to prevent NuGet packages from being versioned in your repository.

<details>
<summary>Example directory structure:</summary>

```plaintext
<Unity Project Location>
├── Assets
│ ├── NuGet.config
│ ├── packages.config
│ └── Packages
│ └── Serilog.2.12.0
│ ├── icon.png
│ └── lib
│ └── netstandard2.1
│ └── Serilog.dll
```

</details>

NuGetForUnity installs packages into the local repository path defined in the _NuGet.config_ file (`repositoryPath`). By default, this is set to the `Assets/Packages` folder. In the _NuGet.config_ file, this can either be a full path, or it can be a relative path based on the project's Assets folder. Note: You'll probably want your Packages folder to be ignored by your version control software to prevent NuGet packages from being versioned in your repository.
### In Packages folder

All configuration files and the installed packages are placed inside `<Unity Project Location>/Packages/nuget-packages`. This way, the `Assets` directory will not contain any files. In this placement method, the path to the _packages.config_ file and the installed packages directory cannot be changed.

<details>
<summary>Example directory structure:</summary>

```plaintext
<Unity Project Location>
├── Packages
│ └── nuget-packages
│ ├── NuGet.config
│ ├── packages.config
│ └── InstalledPackages
│ └── Serilog.2.12.0
│ ├── icon.png
│ └── lib
│ └── netstandard2.1
│ └── Serilog.dll
```

</details>

## Content of _packages.config_ file

When a package is installed, the _packages.config_ file in the project is automatically updated with the specific package information, as well as all of the dependencies that are also installed. This allows for the packages to be restored from scratch at any point. The `Restore` operation is automatically run every time the project is opened or the code is recompiled in the project. It can be run manually by selecting the **NuGet → Restore Packages** menu item.

<img alt="Menu Items" src="docs/screenshots/menu_item.png" height="170px" />

Note: Depending on the size and number of packages you need to install, the `Restore` operation could take a _long_ time, so please be patient. If it appears the Unity isn't launching or responding, wait a few more minutes before attempting to kill the process.

If you are interested in the process NuGetForUnity follows or you are trying to debug an issue, you can force NuGetForUnity to use verbose logging to output an increased amount of data to the Unity console. Add the line `<add key="verbose" value="true" />` to the `<config>` element in the _NuGet.config_ file. You can disable verbose logging by either setting the value to false or completely deleting the line.
## Verbose Logging

If you are interested in the process NuGetForUnity follows or you are trying to debug an issue, you can force NuGetForUnity to use verbose logging to output an increased amount of data to the Unity console. Either check the `Use Verbose Logging` checkbox in the `NuGet For Unity` settings window or add the line `<add key="verbose" value="true" />` to the `<config>` element in the _NuGet.config_ file. You can disable verbose logging by either setting the value to false or completely deleting the line.

## Caching

The _.nupkg_ files downloaded from the NuGet server are cached locally in the current user's Application Data folder `%localappdata%\NuGet\Cache` (`C:\Users\[username]\AppData\Local\NuGet\Cache`). The cache location can be overwritten by setting the `NuGetCachePath` environment variable. Packages previously installed are installed via the cache folder instead of downloading it from the server again.
The _.nupkg_ files downloaded from the NuGet server are cached locally in the current user's Application Data folder `%localappdata%\NuGet\Cache` (Windows: `C:\Users\[username]\AppData\Local\NuGet\Cache`, Mac/Linux: `~/.local/share/NuGet/Cache`). The cache location can be overwritten by setting the `NuGetCachePath` environment variable. Packages previously installed are installed via the cache folder instead of downloading it from the server again.

# Advanced settings

## Use custom NuGet server

The default configuration uses `nuget.org` but package sources hosted on other servers should also work. Some need some special settings. The setting can be either set using configuration UI **NuGet → Preferences** or in the `NuGet.config`. Some examples:
The default configuration uses `nuget.org` but package sources hosted on other servers should also work. Some need some special settings. The setting can be either set using configuration UI **NuGet → Preferences** or in the _NuGet.config_. Some examples:

### Azure Artifacts / GitHub Packages

Expand Down
2 changes: 1 addition & 1 deletion src/NuGetForUnity/Editor/Configuration/NugetConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public string RepositoryPath
}

/// <summary>
/// Gets or sets the incomplete path that is saved. The path is expanded and made public via the property above.
/// Gets or sets the incomplete path that is saved. The path is expanded and made public via the property above.
/// </summary>
[NotNull]
public string ConfiguredRepositoryPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ internal static void Move([NotNull] string newPath)
var oldPath = nugetConfig.PackagesConfigDirectoryPath;

// We need to make sure saved path is using forward slashes so it works on all systems
nugetConfig.PackagesConfigDirectoryPath = newPath.Replace("\\", "/");
nugetConfig.PackagesConfigDirectoryPath = newPath.Replace('\\', '/');
var newFilePath = Path.GetFullPath(Path.Combine(newPath, FileName));
try
{
Expand Down
45 changes: 27 additions & 18 deletions src/NuGetForUnity/Editor/Ui/NugetPreferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,25 +193,27 @@ public override void OnGUI([CanBeNull] string searchContext)
if (GUILayout.Button("Browse", GUILayout.Width(100)))
{
var newPath = EditorUtility.OpenFolderPanel("Select folder where packages will be installed", repositoryPath, string.Empty);
if (!string.IsNullOrEmpty(newPath))
if (!string.IsNullOrEmpty(newPath) &&
newPath != repositoryPath &&
Path.GetFullPath(newPath) != Path.GetFullPath(repositoryPath))
{
var newRelativePath = PathHelper.GetRelativePath(Application.dataPath, newPath);

// We need to make sure saved path is using forward slashes so it works on all systems
newRelativePath = newRelativePath.Replace('\\', '/');

if (newPath != repositoryPath && UnityPathHelper.IsValidInstallPath(newRelativePath))
if (UnityPathHelper.IsValidInstallPath(newRelativePath))
{
PackageContentManager.MoveInstalledPackages(repositoryPath, newPath);
ConfigurationManager.NugetConfigFile.ConfiguredRepositoryPath = newRelativePath;
UnityPathHelper.EnsurePackageInstallDirectoryIsSetup();
preferencesChangedThisFrame = true;
needsAssetRefresh = true;
}
else if (newPath != repositoryPath)
else
{
Debug.LogError(
$"Packages install path {newPath} {newRelativePath} is not valid. It must be somewhere under Assets or Packages folder.");
$"Packages install path '{newPath}' -> '{newRelativePath}' is not valid. It must be somewhere under Assets or Packages folder, else Unity will not import the packages.");
}
}
}
Expand All @@ -230,7 +232,9 @@ public override void OnGUI([CanBeNull] string searchContext)
{
var newPath = EditorUtility.OpenFolderPanel("Select Folder", packagesConfigPath, string.Empty);

if (!string.IsNullOrEmpty(newPath) && newPath != packagesConfigPath)
if (!string.IsNullOrEmpty(newPath) &&
newPath != packagesConfigPath &&
Path.GetFullPath(newPath) != Path.GetFullPath(packagesConfigPath))
{
// if the path root is different or it is not under Assets folder, we want to show a warning message
shouldShowPackagesConfigPathWarning = !UnityPathHelper.IsPathInAssets(newPath);
Expand All @@ -250,21 +254,26 @@ public override void OnGUI([CanBeNull] string searchContext)
}
}

var preferNetStandardOverNetFramework = EditorGUILayout.Toggle(
new GUIContent(
"Prefer .NET Standard dependencies over .NET Framework",
"If a nuget package contains DLL's for .NET Framework an .NET Standard the .NET Standard DLL's are preferred."),
ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework);
if (preferNetStandardOverNetFramework != ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework)
var apiCompatibilityLevelIsNetStandard =
TargetFrameworkResolver.CurrentBuildTargetApiCompatibilityLevel.Value == ApiCompatibilityLevel.NET_Standard_2_0;
using (new DisabledGroupScope(apiCompatibilityLevelIsNetStandard))
{
preferencesChangedThisFrame = true;
ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework = preferNetStandardOverNetFramework;
var preferNetStandardOverNetFramework = EditorGUILayout.Toggle(
new GUIContent(
"Prefer .NET Standard dependencies over .NET Framework",
"If a NuGet package contains DLL's for .NET Framework an .NET Standard the .NET Standard DLL's are preferred."),
ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework);
if (preferNetStandardOverNetFramework != ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework)
{
preferencesChangedThisFrame = true;
ConfigurationManager.NugetConfigFile.PreferNetStandardOverNetFramework = preferNetStandardOverNetFramework;
}
}

if (TargetFrameworkResolver.CurrentBuildTargetApiCompatibilityLevel.Value == ApiCompatibilityLevel.NET_Standard_2_0)
if (apiCompatibilityLevelIsNetStandard)
{
EditorGUILayout.HelpBox(
"The prefer .NET Standard setting has no effect as you have set the API compatibility level to .NET Standard so .NET Standard will always be preferred, as it is the only supported.",
"The 'prefer .NET Standard' setting has no effect as you have set the API compatibility level to .NET Standard so .NET Standard will always be preferred, as it is the only supported.",
MessageType.Info);
}

Expand Down Expand Up @@ -323,17 +332,17 @@ public override void OnGUI([CanBeNull] string searchContext)
source.SavedPath = savedPath;
}

if (GUILayout.Button(upArrow, GUILayout.Width(24)))
if (GUILayout.Button(upArrow, GUILayout.Width(24), GUILayout.Height(20)))
{
sourceToMoveUp = source;
}

if (GUILayout.Button(downArrow, GUILayout.Width(24)))
if (GUILayout.Button(downArrow, GUILayout.Width(24), GUILayout.Height(20)))
{
sourceToMoveDown = source;
}

if (GUILayout.Button(deleteX, GUILayout.Width(24)))
if (GUILayout.Button(deleteX, GUILayout.Width(24), GUILayout.Height(20)))
{
sourceToRemove = source;
}
Expand Down
Loading