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

DYN-5709: Pm publish version patch request #15395

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
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
Prev Previous commit
Next Next commit
new path to publish installed packages
- historically, when publishing a new package or a new package version, we would re-build the package anew every time. This creates a number of issues around tempering with loaded resources (removing, overriding, loading, unloading)
- we make an assumption, that if a package is installed, the user wants to publish (either as a brand new package, or a version) the actual installed package with its existing files and folder structure
- this means that we disable the option to dynamically add/remove files if we publish from locally installed package
- which allows us to simply zip the existing folder structure, only amending the Header file as needed
  • Loading branch information
dnenov committed Jul 18, 2024
commit 09a2a0aa1418a5b6487f2dd9d53958fe59098d95
Original file line number Diff line number Diff line change
@@ -457,15 +457,17 @@ private void PublishNewPackageVersion()
Model.RefreshCustomNodesFromDirectory(dynamoModel.CustomNodeManager, DynamoModel.IsTestMode);
var vm = PublishPackageViewModel.FromLocalPackage(dynamoViewModel, Model, true);
vm.IsNewVersion = true;
vm.IsPackageInstalled = true;

dynamoViewModel.OnRequestPackagePublishDialog(vm);
}

private void PublishNewPackage()
{
Model.RefreshCustomNodesFromDirectory(dynamoModel.CustomNodeManager, DynamoModel.IsTestMode);
var vm = PublishPackageViewModel.FromLocalPackage(dynamoViewModel, Model, false);
var vm = PublishPackageViewModel.FromLocalPackage(dynamoViewModel, Model, true);
vm.IsNewVersion = false;
vm.IsPackageInstalled = true;
Copy link
Contributor

@aparajit-pratap aparajit-pratap Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this always be true? In the case of publishing a new package, the new package doesn't need to always be loaded, does it?


dynamoViewModel.OnRequestPackagePublishDialog(vm);
}
Original file line number Diff line number Diff line change
@@ -211,7 +211,25 @@
}
}
}


/// <summary>
/// IsPackageInstalled property </summary>
/// <value>
/// Shows if the package is already installed </value>
private bool _isPackageInstalled = false;
public bool IsPackageInstalled
{
get { return _isPackageInstalled; }

Check failure on line 222 in src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs

GitHub Actions / analyze

Symbol 'IsPackageInstalled.get' is not part of the declared public API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
set

Check failure on line 223 in src/DynamoCoreWpf/ViewModels/PackageManager/PublishPackageViewModel.cs

GitHub Actions / analyze

Symbol 'IsPackageInstalled.set' is not part of the declared public API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
{
if (_isPackageInstalled != value)
{
_isPackageInstalled = value;
RaisePropertyChanged(nameof(IsPackageInstalled));
}
}
}

/// <summary>
/// CanEditName property </summary>
/// <value>
@@ -956,8 +974,8 @@
customNodeDefinitions = new List<CustomNodeDefinition>();
SubmitCommand = new DelegateCommand(Submit, CanSubmit);
PublishLocallyCommand = new DelegateCommand(PublishLocally, CanPublishLocally);
ShowAddFileDialogAndAddCommand = new DelegateCommand(ShowAddFileDialogAndAdd, CanShowAddFileDialogAndAdd);
SelectDirectoryAndAddFilesRecursivelyCommand = new DelegateCommand(SelectDirectoryAndAddFilesRecursively);
ShowAddFileDialogAndAddCommand = new DelegateCommand(ShowAddFileDialogAndAdd, CanAddFiles);
SelectDirectoryAndAddFilesRecursivelyCommand = new DelegateCommand(SelectDirectoryAndAddFilesRecursively, CanAddFiles);
SelectMarkdownDirectoryCommand = new DelegateCommand(SelectMarkdownDirectory);
ClearMarkdownDirectoryCommand = new DelegateCommand(ClearMarkdownDirectory);
CancelCommand = new DelegateCommand(Cancel);
@@ -1364,7 +1382,7 @@
{
if (e.PropertyName == "PackageContents")
{
CanSubmit();
CanSubmit();
SubmitCommand.RaiseCanExecuteChanged();
PublishLocallyCommand.RaiseCanExecuteChanged();
}
@@ -1493,6 +1511,7 @@
/// <summary>
/// The method is used to create a PublishPackageViewModel from a Package object.
/// If retainFolderStructure is set to true, the folder structure of the package will be retained. Else, the default folder structure will be imposed.
/// Investigating if both options (publish and publish new version) should not use 'retainFolderStructure' with disabled package files and folders editing
/// </summary>
/// <param name="dynamoViewModel"></param>
/// <param name="pkg">The package to be loaded</param>
@@ -2117,9 +2136,9 @@
}
}

private bool CanShowAddFileDialogAndAdd()
private bool CanAddFiles()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just remove this redundant property (it's just the inverse of IsPackageInstalled) and use IsPackageInstalled directly?

{
return true;
return !IsPackageInstalled;
}

internal void AddFile(string filename)
@@ -2267,7 +2286,15 @@
{
// begin submission
var pmExtension = dynamoViewModel.Model.GetPackageManagerExtension();
var handle = pmExtension.PackageManagerClient.PublishAsync(Package, RetainFolderStructureOverride ? updatedFiles : contentFiles, MarkdownFiles, IsNewVersion, CurrentPackageRootDirectories, RetainFolderStructureOverride);
PackageUploadHandle handle;
if (IsPackageInstalled)
{
handle = pmExtension.PackageManagerClient.PublishInstalledPackageAsync(Package, IsNewVersion);
}
else
{
handle = pmExtension.PackageManagerClient.PublishAsync(Package, RetainFolderStructureOverride ? updatedFiles : contentFiles, MarkdownFiles, IsNewVersion, CurrentPackageRootDirectories, RetainFolderStructureOverride);
}

// start upload
Uploading = true;
@@ -2601,10 +2628,12 @@
}

/// <summary>
/// Delegate used to publish the element locally </summary>
/// Delegate used to publish the element locally
/// If the package is already installed (and therefore loaded), we shouldn't be able to publish it locally again?
/// </summary>
private bool CanPublishLocally()
{
return CheckPackageValidity();
return !IsPackageInstalled && CheckPackageValidity();
}

private bool CheckPackageValidity()
2 changes: 1 addition & 1 deletion src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs
Original file line number Diff line number Diff line change
@@ -1517,7 +1517,7 @@ private void DynamoViewModelRequestPackageManager(PublishPackageViewModel model)
WindowStartupLocation = WindowStartupLocation.CenterOwner
};

// setting the owner to the packageManagerWindow will centralize promts originating from the Package Manager
// setting the owner to the packageManagerWindow will centralize prompts originating from the Package Manager
dynamoViewModel.Owner = packageManagerWindow;

packageManagerWindow.Closed += HandlePackageManagerWindowClosed;
Original file line number Diff line number Diff line change
@@ -427,6 +427,11 @@
Property="Fill"
Value="#6AC0E7" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Folder"
Property="Fill"
Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
@@ -465,6 +470,11 @@
Property="Fill"
Value="#6AC0E7" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Folder"
Property="Fill"
Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
@@ -475,6 +485,7 @@
<local:CustomBrowserControl x:Name="customBrowserControl"
Grid.Column="0" Grid.Row="1"
Loaded="customBrowserControl_Loaded"
DisableRemove="{Binding IsPackageInstalled}"
Root="{Binding PackageContents, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />

<!--Files-->
@@ -487,6 +498,7 @@
CanUserSortColumns="True"
VerticalScrollBarVisibility="Disabled"
ItemsSource="{Binding RootContents, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
IsEnabled="{Binding IsPackageInstalled, Converter={StaticResource BooleanNegationConverter}}"
Style="{StaticResource DataGrid}">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" BasedOn="{StaticResource DataGridRowStyle}">
@@ -599,9 +611,9 @@
Height="15"
VerticalAlignment="Center"
Margin="0 5"
IsEnabled="True"
IsChecked="{Binding Path=RetainFolderStructureOverride, Mode=TwoWay}"
IsTabStop="False"
IsEnabled="{Binding IsPackageInstalled, Converter={StaticResource BooleanNegationConverter}}"
Style="{StaticResource EllipseToggleButton1}" />
<TextBlock Text="{x:Static p:Resources.PublishPackageRetainFolderStructureToggleButtonText}"
Style="{StaticResource LabelStyle}"
19 changes: 18 additions & 1 deletion src/DynamoPackages/PackageDirectoryBuilder.cs
Original file line number Diff line number Diff line change
@@ -12,10 +12,10 @@ public interface IPackageDirectoryBuilder
{
IDirectoryInfo BuildDirectory(Package packages, string packagesDirectory, IEnumerable<string> files, IEnumerable<string> markdownfiles);
IDirectoryInfo BuildRetainDirectory(Package package, string packagesDirectory, IEnumerable<string> roots, IEnumerable<IEnumerable<string>> contentFiles, IEnumerable<string> markdownFiles);
IDirectoryInfo BuildPackageHeader(Package package, string packagesDirectory);

[Obsolete]
IDirectoryInfo BuildRetainDirectory(Package package, string packagesDirectory, IEnumerable<IEnumerable<string>> contentFiles, IEnumerable<string> markdownFiles);

}

/// <summary>
@@ -125,6 +125,23 @@ public IDirectoryInfo BuildRetainDirectory(Package package, string packagesDirec
return rootDir;
}

/// <summary>
/// Builds package header in the provided package directory
/// </summary>
/// <param name="package">The already installed package</param>
/// <param name="packagesDirectory">The package installation folder</param>
/// <returns></returns>
public IDirectoryInfo BuildPackageHeader(Package package, string packagesDirectory)
{
var rootPath = Path.Combine(packagesDirectory, package.Name);
var rootDir = fileSystem.TryCreateDirectory(rootPath);
package.RootDirectory = rootDir.FullName;

WritePackageHeader(package, rootDir);

return rootDir;
}

public static void PreBuildDirectory(string packageName, string packagesDirectory,
out string rootDir, out string dyfDir, out string binDir, out string extraDir, out string docDir)
{
56 changes: 56 additions & 0 deletions src/DynamoPackages/PackageManagerClient.cs
Original file line number Diff line number Diff line change
@@ -251,6 +251,62 @@ internal PackageUploadHandle PublishAsync(Package package, object files, IEnumer
return packageUploadHandle;
}


internal PackageUploadHandle PublishInstalledPackageAsync(Package package, bool isNewVersion)
{
var packageUploadHandle = new PackageUploadHandle(PackageUploadBuilder.NewRequestBody(package));

Task.Factory.StartNew(() =>
{
Publish(package, isNewVersion, packageUploadHandle);
});

return packageUploadHandle;
}

internal void Publish(Package package, bool isNewVersion, PackageUploadHandle packageUploadHandle)
{
try
{
ResponseBody ret = null;
if (isNewVersion)
{
var pkg = uploadBuilder.InstalledPackageVersionUpload(package, packageUploadDirectory, packageUploadHandle);
packageUploadHandle.UploadState = PackageUploadHandle.State.Uploading;
ret = this.client.ExecuteAndDeserialize(pkg);
}
else
{
var pkg = uploadBuilder.InstalledPackageUpload(package, packageUploadDirectory, packageUploadHandle);
packageUploadHandle.UploadState = PackageUploadHandle.State.Uploading;
ret = this.client.ExecuteAndDeserialize(pkg);
}
if (ret == null)
{
packageUploadHandle.Error("Failed to submit. Try again later.");
return;
}

if (ret != null && !ret.success)
{
packageUploadHandle.Error(ret.message);
return;
}
packageUploadHandle.Done(null);
}
catch (Exception ex)
{
if (ex is IOException || ex is UnauthorizedAccessException)
{
packageUploadHandle.Error(DynamoPackages.Properties.Resources.CannotRemovePackageAssemblyTitle + ": " + DynamoPackages.Properties.Resources.CannotRemovePackageAssemblyMessage + "(" + ex.Message + ")");
}
else
{
packageUploadHandle.Error(ex.GetType() + ": " + ex.Message);
}
}
}

internal void Publish(Package package, object files, IEnumerable<string> markdownFiles, bool isNewVersion, PackageUploadHandle packageUploadHandle, IEnumerable<string> roots, bool retainFolderStructure = false)
{
try
57 changes: 53 additions & 4 deletions src/DynamoPackages/PackageUploadBuilder.cs
Original file line number Diff line number Diff line change
@@ -15,11 +15,15 @@ PackageUpload NewPackageUpload(Package package, string packagesDirectory, IEnume
PackageUpload NewPackageRetainUpload(Package package, string packagesDirectory, IEnumerable<string> roots, IEnumerable<IEnumerable<string>> files, IEnumerable<string> markdownFiles,
PackageUploadHandle handle);

PackageVersionUpload NewPackageVersionUpload(Package package, string packagesDirectory,
IEnumerable<string> files, IEnumerable<string> markdownFiles, PackageUploadHandle handle);
PackageVersionUpload NewPackageVersionUpload(Package package, string packagesDirectory, IEnumerable<string> files, IEnumerable<string> markdownFiles,
PackageUploadHandle handle);

PackageVersionUpload NewPackageVersionRetainUpload(Package package, string packagesDirectory, IEnumerable<string> roots, IEnumerable<IEnumerable<string>> files, IEnumerable<string> markdownFiles,
PackageUploadHandle handle);

PackageVersionUpload NewPackageVersionRetainUpload(Package package, string packagesDirectory, IEnumerable<string> roots,
IEnumerable<IEnumerable<string>> files, IEnumerable<string> markdownFiles, PackageUploadHandle handle);
PackageUpload InstalledPackageUpload(Package package, string packagesDirectory, PackageUploadHandle handle);

PackageVersionUpload InstalledPackageVersionUpload(Package package, string packagesDirectory, PackageUploadHandle handle);
}

internal class PackageUploadBuilder : IPackageUploadBuilder
@@ -188,6 +192,40 @@ public PackageVersionUpload NewPackageVersionRetainUpload(Package package, strin
return new PackageVersionUpload(NewRequestBody(package), BuildAndZip(package, packagesDirectory, files, markdownFiles, handle).Name);
}

/// <summary>
/// Publishes an installed package
/// </summary>
/// <param name="package"></param>
/// <param name="packagesDirectory"></param>
/// <param name="handle"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public PackageUpload InstalledPackageUpload(Package package, string packagesDirectory, PackageUploadHandle handle)
{
if (package == null) throw new ArgumentNullException("package");
if (packagesDirectory == null) throw new ArgumentNullException("packagesDirectory");
if (handle == null) throw new ArgumentNullException("handle");

return new PackageUpload(NewRequestBody(package), BuildAndZip(package, packagesDirectory, handle).Name);
}


/// <summary>
/// Publishes a new version of an installed package
/// </summary>
/// <param name="package"></param>
/// <param name="packagesDirectory"></param>
/// <param name="handle"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public PackageVersionUpload InstalledPackageVersionUpload(Package package, string packagesDirectory, PackageUploadHandle handle)
{
if (package == null) throw new ArgumentNullException("package");
if (packagesDirectory == null) throw new ArgumentNullException("packagesDirectory");
if (handle == null) throw new ArgumentNullException("handle");

return new PackageVersionUpload(NewRequestBody(package), BuildAndZip(package, packagesDirectory, handle).Name);
}
#endregion

#region Private Class Methods
@@ -226,6 +264,17 @@ private IFileInfo BuildAndZip(Package package, string packagesDirectory, IEnumer
return Zip(dir);
}

private IFileInfo BuildAndZip(Package package, string packagesDirectory, PackageUploadHandle handle)
{
handle.UploadState = PackageUploadHandle.State.Copying;

var dir = builder.BuildPackageHeader(package, packagesDirectory);

handle.UploadState = PackageUploadHandle.State.Compressing;

return Zip(dir);
}


private IFileInfo Zip(IDirectoryInfo directory)
{
Loading