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

Feature/42313 Deep link Git Solution Open #4011

Merged
merged 5 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
24 changes: 8 additions & 16 deletions Ginger/Ginger/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ limitations under the License.
using GingerWPF.WorkSpaceLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
Expand Down Expand Up @@ -258,7 +256,6 @@ private async void Application_Startup(object sender, StartupEventArgs e)
try
{
InitLogging();

bool startGrid = ShouldStartGrid(e.Args);
WorkSpace.Init(new WorkSpaceEventHandler(), startGrid);
var parserResult = ParseCommandLineArguments(e.Args);
Expand All @@ -284,7 +281,7 @@ private async void Application_Startup(object sender, StartupEventArgs e)
{
Reporter.ToLog(eLogLevel.ERROR, "Unhandled exception in Application_Startup", ex);
}
}
}


/// <summary>
Expand Down Expand Up @@ -326,11 +323,11 @@ private ParserResult<object> ParseCommandLineArguments(string[] args)
input = System.Web.HttpUtility.UrlDecode(input);
if (input.StartsWith("ginger://"))
{
input = input.Substring("ginger://".Length);
input = input["ginger://".Length..];
}
if (input.EndsWith("/"))
{
input = input.Substring(0, input.Length - 1);
input = input[..^1];
}
List<string> resultList = General.SplitWithPaths(input).Select(s => s.Trim('\"', '\'')).ToList();
arguments = resultList.ToArray();
Expand All @@ -351,7 +348,7 @@ private ParserResult<object> ParseCommandLineArguments(string[] args)
/// <returns>DoOptions object or null.</returns>
private DoOptions ExtractDoOptions(ParserResult<object> parserResult)
{
if (parserResult?.Value is DoOptions tempOptions && tempOptions.Operation == DoOptions.DoOperation.open)
if (parserResult?.Value is DoOptions tempOptions && (tempOptions.Operation == DoOptions.DoOperation.open))
{
return tempOptions;
}
Expand Down Expand Up @@ -417,15 +414,10 @@ private void ProcessGingerUIStartup(DoOptions doOptions)

if (doOptions != null && !string.IsNullOrWhiteSpace(doOptions.Solution))
{
if(Directory.Exists(doOptions.Solution))
{
DoOptionsHandler.Run(doOptions);
}
else
{
Reporter.ToLog(eLogLevel.ERROR, "The specified solution folder path does not exist. Please check the path and try again.");
}


new DoOptionsHandler().Run(doOptions);


}
}
finally
Expand Down
44 changes: 42 additions & 2 deletions Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ limitations under the License.
using AccountReport.Contracts.ResponseModels;
using amdocs.ginger.GingerCoreNET;
using Amdocs.Ginger.Common;
using Amdocs.Ginger.CoreNET.Execution;
using Amdocs.Ginger.CoreNET.Run.RunListenerLib.CenteralizedExecutionLogger;
using Amdocs.Ginger.Repository;
using Ginger;
using Ginger.AnalyzerLib;
using Ginger.Configurations;
using Ginger.ExecuterService.Contracts.V1.ExecutionConfiguration;
Expand All @@ -46,7 +46,7 @@ public enum eCLIType
Config, Dynamic, Script, Arguments
}

public class CLIHelper : INotifyPropertyChanged
public class CLIHelper : SourceControlOptions, INotifyPropertyChanged
{
public string Solution;
public string Env;
Expand Down Expand Up @@ -215,6 +215,46 @@ public bool UndoSolutionLocalChanges
//UserProfile WorkSpace.Instance.UserProfile;
RunSetConfig mRunSetConfig;

/// <summary>
/// Adds CLI Git properties from the provided SourceControlOptions.
/// </summary>
/// <param name="runOptions">The SourceControlOptions containing the Git properties.</param>
internal void AddCLIGitProperties(SourceControlOptions runOptions)
{
SourceControlURL = runOptions.URL;
SourcecontrolUser = runOptions.User;
sourceControlType = runOptions.SCMType;
SetSourceControlBranch(runOptions.Branch);
sourceControlPass = runOptions.Pass;
sourceControlPassEncrypted = runOptions.PasswordEncrypted;
SourceControlProxyServer(runOptions.SourceControlProxyServer);
SourceControlProxyPort(runOptions.SourceControlProxyPort);
}
GokulBothe99 marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Sets the workspace Git properties from the provided SourceControlOptions.
/// </summary>
/// <param name="runOptions">The SourceControlOptions containing the Git properties.</param>
internal void SetWorkSpaceGitProperties(SourceControlOptions runOptions)
{
if (WorkSpace.Instance.UserProfile == null)
{
WorkSpace.Instance.UserProfile = new UserProfile();
UserProfileOperations userProfileOperations = new UserProfileOperations(WorkSpace.Instance.UserProfile);
WorkSpace.Instance.UserProfile.UserProfileOperations = userProfileOperations;
}
WorkSpace.Instance.UserProfile.SourceControlURL = runOptions.URL;
WorkSpace.Instance.UserProfile.SourceControlUser = runOptions.User;
WorkSpace.Instance.UserProfile.SourceControlType = runOptions.SCMType;
WorkSpace.Instance.UserProfile.UserProfileOperations.SourceControlIgnoreCertificate = runOptions.ignoreCertificate;
WorkSpace.Instance.UserProfile.UserProfileOperations.SourceControlUseShellClient = runOptions.useScmShell;
WorkSpace.Instance.UserProfile.EncryptedSourceControlPass = runOptions.Pass;
WorkSpace.Instance.UserProfile.SourceControlPass = runOptions.Pass;
}
/// <summary>
/// Loads the solution.
/// </summary>
/// <returns>True if the solution is loaded successfully, otherwise false.</returns>
public bool LoadSolution()
{
try
Expand Down
37 changes: 4 additions & 33 deletions Ginger/GingerCoreNET/RunLib/CLILib/CLIProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ limitations under the License.
using Amdocs.Ginger.CoreNET.log4netLib;
using Amdocs.Ginger.CoreNET.RunLib.CLILib;
using CommandLine;
using Ginger;
using GingerCore;
using GingerCoreNET.RunLib;
using System;
Expand All @@ -40,7 +39,7 @@ namespace Amdocs.Ginger.CoreNET.RunLib
public class CLIProcessor
{
ICLI mCLIHandler;
CLIHelper mCLIHelper = new CLIHelper();
CLIHelper mCLIHelper = new();

public async Task ExecuteArgs(string[] args)
{
Expand Down Expand Up @@ -116,7 +115,7 @@ private async Task<int> HandleDoOptions(DoOptions opts)
{
try
{
DoOptionsHandler.Run(opts);
new DoOptionsHandler().Run(opts);
return 0;
}
catch (Exception ex)
Expand Down Expand Up @@ -392,26 +391,15 @@ private async Task<int> HandleRunOptions(RunOptions runOptions)
Reporter.ToLog(eLogLevel.INFO, "Loading Configurations...");

mCLIHandler = new CLIArgs();
mCLIHelper.AddCLIGitProperties(runOptions);
mCLIHelper.Solution = runOptions.Solution;
mCLIHelper.SetEncryptionKey(runOptions.EncryptionKey);
mCLIHelper.Runset = runOptions.Runset;
mCLIHelper.Env = runOptions.Environment;
mCLIHelper.RunAnalyzer = !runOptions.DoNotAnalyze;
mCLIHelper.ShowAutoRunWindow = runOptions.ShowUI;
mCLIHelper.TestArtifactsFolder = runOptions.TestArtifactsPath;

mCLIHelper.SourceControlURL = runOptions.URL;
mCLIHelper.SourcecontrolUser = runOptions.User;
mCLIHelper.sourceControlType = runOptions.SCMType;

mCLIHelper.SetSourceControlBranch(runOptions.Branch);

mCLIHelper.sourceControlPass = runOptions.Pass;
mCLIHelper.sourceControlPassEncrypted = runOptions.PasswordEncrypted;
mCLIHelper.SourceControlProxyServer(runOptions.SourceControlProxyServer);
mCLIHelper.SourceControlProxyPort(runOptions.SourceControlProxyPort);
mCLIHelper.SelfHealingCheckInConfigured = runOptions.SelfHealingCheckInConfigured;

mCLIHelper.SealightsEnable = runOptions.SealightsEnable;
mCLIHelper.SealightsUrl = runOptions.SealightsUrl;
mCLIHelper.SealightsAgentToken = runOptions.SealightsAgentToken;
Expand All @@ -421,8 +409,6 @@ private async Task<int> HandleRunOptions(RunOptions runOptions)
mCLIHelper.SealightsTestStage = runOptions.SealightsTestStage;
mCLIHelper.SealightsEntityLevel = runOptions.SealightsEntityLevel?.ToString() == "None" ? null : runOptions.SealightsEntityLevel?.ToString();
mCLIHelper.SealightsTestRecommendations = runOptions.SealightsTestRecommendations;

//set source application and source app user
mCLIHelper.SourceApplication = runOptions.SourceApplication;
mCLIHelper.SourceApplicationUser = runOptions.SourceApplicationUser;

Expand Down Expand Up @@ -461,22 +447,7 @@ private async Task<int> HandleRunOptions(RunOptions runOptions)
mCLIHelper.RerunLevel = runOptions.RerunLevel;
}

if (WorkSpace.Instance.UserProfile == null)
{
WorkSpace.Instance.UserProfile = new UserProfile();
UserProfileOperations userProfileOperations = new UserProfileOperations(WorkSpace.Instance.UserProfile);
WorkSpace.Instance.UserProfile.UserProfileOperations = userProfileOperations;
}
WorkSpace.Instance.UserProfile.SourceControlURL = runOptions.URL;
WorkSpace.Instance.UserProfile.SourceControlUser = runOptions.User;
WorkSpace.Instance.UserProfile.SourceControlType = runOptions.SCMType;
WorkSpace.Instance.UserProfile.UserProfileOperations.SourceControlIgnoreCertificate = runOptions.ignoreCertificate;
WorkSpace.Instance.UserProfile.UserProfileOperations.SourceControlUseShellClient = runOptions.useScmShell;



WorkSpace.Instance.UserProfile.EncryptedSourceControlPass = runOptions.Pass;
WorkSpace.Instance.UserProfile.SourceControlPass = runOptions.Pass;
mCLIHelper.SetWorkSpaceGitProperties(runOptions);
if (runOptions.PasswordEncrypted)
{
mCLIHandler.LoadGeneralConfigurations("", mCLIHelper);
Expand Down
7 changes: 5 additions & 2 deletions Ginger/GingerCoreNET/RunLib/CLILib/DoOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ limitations under the License.
using CommandLine;
using System;
using System.IO;
using System.Net;

namespace Amdocs.Ginger.CoreNET.RunLib.CLILib
{

[Verb("do", HelpText = "Solution Operations like: analyze, clean and more for list run 'ginger help solution")]
public class DoOptions // 'ginger do --operation analyze' run analyzer on solution
public class DoOptions : SourceControlOptions // 'ginger do --operation analyze' run analyzer on solution
{
public enum DoOperation
{
Expand Down Expand Up @@ -60,6 +59,10 @@ public string Solution
}


[Option('e', "encryptionKey", Required = false, HelpText = "Provide the solution encyrption key")]
public string EncryptionKey { get; set; }
GokulBothe99 marked this conversation as resolved.
Show resolved Hide resolved


}

}
73 changes: 55 additions & 18 deletions Ginger/GingerCoreNET/RunLib/CLILib/DoOptionsHanlder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,59 @@ limitations under the License.

namespace Amdocs.Ginger.CoreNET.RunLib.CLILib
{
public static class DoOptionsHandler

public class DoOptionsHandler
{
public static void Run(DoOptions opts)
DoOptions mOpts;
CLIHelper mCLIHelper = new();
GokulBothe99 marked this conversation as resolved.
Show resolved Hide resolved
public void Run(DoOptions opts)
{
mOpts = opts;
switch (opts.Operation)
{
case DoOptions.DoOperation.analyze:
DoAnalyze(opts.Solution);
DoAnalyze();
break;
case DoOptions.DoOperation.clean:
// TODO: remove execution folder, backups and more
break;
case DoOptions.DoOperation.info:
DoInfo(opts.Solution);
DoInfo();
break;
case DoOptions.DoOperation.open:
DoOpen(opts.Solution);
DoOpen();
break;
}
}

GokulBothe99 marked this conversation as resolved.
Show resolved Hide resolved
private static void DoInfo(string solution)


/// <summary>
/// Decrypts the source control password if it is encrypted.
/// </summary>
/// <param name="runOptions">The options containing the encrypted password and encryption key.</param>
private static void PasswordEncrypted(DoOptions runOptions)
{
Reporter.ToLog(eLogLevel.DEBUG, $"PasswordEncrypted: '{runOptions.PasswordEncrypted}'");
string pswd = WorkSpace.Instance.UserProfile.SourceControlPass;
if (runOptions.PasswordEncrypted.ToString() is "Y" or "true" or "True")
{
try
{
pswd = EncryptionHandler.DecryptwithKey(WorkSpace.Instance.UserProfile.SourceControlPass, runOptions.EncryptionKey);
}
catch (Exception ex)
{
string mess = ex.Message; //To avoid warning of ex not used
Reporter.ToLog(eLogLevel.ERROR, "Failed to decrypt the source control password");//not showing ex details for not showing the password by mistake in log
}
}
WorkSpace.Instance.UserProfile.SourceControlPass = pswd;
}
GokulBothe99 marked this conversation as resolved.
Show resolved Hide resolved
private void DoInfo()
{
// TODO: print info on solution, how many BFs etc, try to read all items - for Linux deser test
WorkSpace.Instance.OpenSolution(solution);
WorkSpace.Instance.OpenSolution(mOpts.Solution);
StringBuilder stringBuilder = new StringBuilder(Environment.NewLine);
stringBuilder.Append("Solution Name :").Append(WorkSpace.Instance.Solution.Name).Append(Environment.NewLine);
stringBuilder.Append("Business Flows :").Append(WorkSpace.Instance.SolutionRepository.GetAllRepositoryItems<BusinessFlow>().Count).Append(Environment.NewLine);
Expand All @@ -61,8 +89,15 @@ private static void DoInfo(string solution)
Reporter.ToLog(eLogLevel.INFO, stringBuilder.ToString());
}

private static void DoOpen(string solutionFolder)
/// <summary>
/// Opens the solution specified in the options.
/// </summary>
/// <param name="solutionFolder">The folder path of the solution to open.</param>
/// <param name="encryptionKey">The encryption key for the solution, if any.</param>
private void DoOpen()
{
string solutionFolder = mOpts.Solution;
string encryptionKey = mOpts.EncryptionKey;
try
{
// Check if solutionFolder is null or empty
Expand All @@ -71,7 +106,6 @@ private static void DoOpen(string solutionFolder)
Reporter.ToLog(eLogLevel.ERROR, "The provided solution folder path is null or empty.");
return;
}

// Check if the folder path contains the solution file name
if (solutionFolder.Contains("Ginger.Solution.xml"))
{
Expand All @@ -84,25 +118,28 @@ private static void DoOpen(string solutionFolder)
}
}

// Check if the directory exists
if (!Directory.Exists(solutionFolder))
// Attempt to open the solution
mCLIHelper.AddCLIGitProperties(mOpts);
mCLIHelper.SetWorkSpaceGitProperties(mOpts);
if (mOpts.PasswordEncrypted)
{
Reporter.ToLog(eLogLevel.ERROR, $"The provided folder path '{solutionFolder}' does not exist.");
return;
PasswordEncrypted(mOpts);
}
mCLIHelper.Solution = mOpts.Solution;
if (!mCLIHelper.LoadSolution())
{
Reporter.ToLog(eLogLevel.ERROR, "Failed to Download/update Solution from source control");
}

// Attempt to open the solution
WorkSpace.Instance.OpenSolution(solutionFolder);
}
catch (Exception ex)
{
// Handle any other unexpected errors
Reporter.ToLog(eLogLevel.ERROR, $"An unexpected error occurred while opening the solution in folder '{solutionFolder}'. Error: {ex.Message}");
}
}
private static void DoAnalyze(string solution)
private void DoAnalyze()
{
WorkSpace.Instance.OpenSolution(solution);
WorkSpace.Instance.OpenSolution(mOpts.Solution);

AnalyzerUtils analyzerUtils = new AnalyzerUtils();
ObservableList<AnalyzerItemBase> issues = [];
Expand Down
Loading
Loading