From 2e8a2d5a1a2e5684477c5198e635e89b94e0b63d Mon Sep 17 00:00:00 2001 From: Vemund Gaukstad Date: Thu, 17 Aug 2023 09:45:57 +0200 Subject: [PATCH 1/2] Add tool for upgrading from v7 to v8 --- cli-tools/altinn-app-upgrade-cli/Makefile | 21 +++ cli-tools/altinn-app-upgrade-cli/Program.cs | 176 ++++++++++++++++++ .../altinn-app-upgrade-cli.csproj | 26 +++ .../v7Tov8/CodeRewriters/TypesRewriter.cs | 152 +++++++++++++++ .../v7Tov8/CodeRewriters/UsingRewriter.cs | 91 +++++++++ .../v7Tov8/ProcessRewriter/ProcessUpgrader.cs | 168 +++++++++++++++++ .../ProjectRewriters/ProjectFileRewriter.cs | 53 ++++++ 7 files changed, 687 insertions(+) create mode 100644 cli-tools/altinn-app-upgrade-cli/Makefile create mode 100644 cli-tools/altinn-app-upgrade-cli/Program.cs create mode 100644 cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj create mode 100644 cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs create mode 100644 cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs create mode 100644 cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs create mode 100644 cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs diff --git a/cli-tools/altinn-app-upgrade-cli/Makefile b/cli-tools/altinn-app-upgrade-cli/Makefile new file mode 100644 index 000000000..11b5ab955 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/Makefile @@ -0,0 +1,21 @@ +# Path: Makefile + +build: + dotnet build + +executable-osx-x64: + dotnet publish -c Release -o publish/osx-x64 -r osx-x64 --self-contained + +executable-osx-arm64: + dotnet publish -c Release -o publish/osx-arm64 -r osx-arm64 + +executable-win-x64: + dotnet publish -c Release -o publish/win-x64 -r win-x64 + +executable-linux-x64: + dotnet publish -c Release -o publish/linux-x64 -r linux-x64 + +executable-linux-arm64: + dotnet publish -c Release -o publish/linux-arm64 -r linux-arm64 + +executables: executable-osx-x64 executable-osx-arm64 executable-win-x64 executable-linux-x64 executable-linux-arm64 \ No newline at end of file diff --git a/cli-tools/altinn-app-upgrade-cli/Program.cs b/cli-tools/altinn-app-upgrade-cli/Program.cs new file mode 100644 index 000000000..70a08e100 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/Program.cs @@ -0,0 +1,176 @@ +using System.CommandLine; +using altinn_app_upgrade_cli.v7Tov8.CodeRewriters; +using altinn_app_upgrade_cli.v7Tov8.ProcessRewriter; +using altinn_app_upgrade_cli.v7Tov8.ProjectRewriters; +using Microsoft.Build.Locator; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.MSBuild; + +namespace altinn_app_upgrade_cli; + +class Program +{ + static async Task Main(string[] args) + { + int returnCode = 0; + var projectFolderOption = new Option(name: "--folder", description: "The project folder to read", getDefaultValue: () => "CurrentDirectory"); + var projectFileOption = new Option(name: "--project", description: "The project file to read relative to --folder", getDefaultValue: () => "App/App.csproj"); + var processFileOption = new Option(name: "--process", description: "The process file to read relative to --folder", getDefaultValue: () => "App/config/process/process.bpmn"); + var targetVersionOption = new Option(name: "--target-version", description: "The target version to upgrade to", getDefaultValue: () => "8.0.0-preview.9"); + var skipCsprojUpgradeOption = new Option(name: "--skip-csproj-upgrade", description: "Skip csproj file upgrade", getDefaultValue: () => false); + var skipCodeUpgradeOption = new Option(name: "--skip-code-upgrade", description: "Skip code upgrade", getDefaultValue: () => false); + var skipProcessUpgradeOption = new Option(name: "--skip-process-upgrade", description: "Skip process file upgrade", getDefaultValue: () => false); + var rootCommand = new RootCommand("Sample app for System.CommandLine"); + var upgradeCommand = new Command("upgrade", "Upgrade an app") + { + projectFolderOption, + projectFileOption, + processFileOption, + targetVersionOption, + skipCsprojUpgradeOption, + skipCodeUpgradeOption, + skipProcessUpgradeOption, + }; + rootCommand.AddCommand(upgradeCommand); + + upgradeCommand.SetHandler(async (projectFolder, projectFile, processFile, targetVersion, skipCodeUpgrade, skipProcessUpgrade, skipCsprojUpgrade) => + { + if (projectFolder == "CurrentDirectory") + { + projectFolder = Directory.GetCurrentDirectory(); + } + + if (File.Exists(projectFolder)) + { + Console.WriteLine($"Project folder {projectFolder} does not exist. Please supply location of project with --project-folder [path/to/project]"); + returnCode = 1; + return; + } + + FileAttributes attr = File.GetAttributes(projectFolder); + if ((attr & FileAttributes.Directory) != FileAttributes.Directory) + { + Console.WriteLine($"Project folder {projectFolder} is a file. Please supply location of project with --project-folder [path/to/project]"); + returnCode = 1; + return; + } + + if (!Path.IsPathRooted(projectFolder)) + { + projectFile = Path.Combine(Directory.GetCurrentDirectory(), projectFolder, projectFile); + processFile = Path.Combine(Directory.GetCurrentDirectory(), projectFolder, processFile); + } + else + { + projectFile = Path.Combine(projectFolder, projectFile); + processFile = Path.Combine(projectFolder, processFile); + } + + if (!skipCsprojUpgrade) + { + returnCode = await UpgradeNugetVersions(projectFile, targetVersion); + } + + if (!skipCodeUpgrade && returnCode == 0) + { + returnCode = await UpgradeCode(projectFile); + } + + if (!skipProcessUpgrade && returnCode == 0) + { + returnCode = await UpgradeProcess(processFile); + } + + if (returnCode == 0) + { + Console.WriteLine("Upgrade completed without errors. Please verify that the application is still working as expected."); + } + else + { + Console.WriteLine("Upgrade completed with errors. Please check for errors in the log above."); + } + }, + projectFolderOption, projectFileOption, processFileOption, targetVersionOption, skipCodeUpgradeOption, skipProcessUpgradeOption, skipCsprojUpgradeOption); + + await rootCommand.InvokeAsync(args); + return returnCode; + } + + static async Task UpgradeNugetVersions(string projectFile, string targetVersion) + { + if (!File.Exists(projectFile)) + { + Console.WriteLine($"Project file {projectFile} does not exist. Please supply location of project with --project [path/to/project.csproj]"); + return 1; + } + + Console.WriteLine("Trying to upgrade nuget versions in project file"); + var rewriter = new ProjectFileRewriter(projectFile, targetVersion); + await rewriter.Upgrade(); + Console.WriteLine("Nuget versions upgraded"); + return 0; + } + + static async Task UpgradeCode(string projectFile) + { + if (!File.Exists(projectFile)) + { + Console.WriteLine($"Project file {projectFile} does not exist. Please supply location of project with --project [path/to/project.csproj]"); + return 1; + } + + Console.WriteLine("Trying to upgrade references and using in code"); + + MSBuildLocator.RegisterDefaults(); + var workspace = MSBuildWorkspace.Create(); + var project = await workspace.OpenProjectAsync(projectFile); + var comp = await project.GetCompilationAsync(); + if (comp == null) + { + Console.WriteLine("Could not get compilation"); + return 1; + } + foreach (var sourceTree in comp.SyntaxTrees) + { + SemanticModel sm = comp.GetSemanticModel(sourceTree); + TypesRewriter rewriter = new(sm); + SyntaxNode newSource = rewriter.Visit(await sourceTree.GetRootAsync()); + if (newSource != await sourceTree.GetRootAsync()) + { + await File.WriteAllTextAsync(sourceTree.FilePath, newSource.ToFullString()); + } + UsingRewriter usingRewriter = new(); + var newUsingSource = usingRewriter.Visit(newSource); + if (newUsingSource != newSource) + { + await File.WriteAllTextAsync(sourceTree.FilePath, newUsingSource.ToFullString()); + } + } + + Console.WriteLine("References and using upgraded"); + return 0; + } + + static async Task UpgradeProcess(string processFile) + { + if (!File.Exists(processFile)) + { + Console.WriteLine($"Process file {processFile} does not exist. Please supply location of project with --process [path/to/project.csproj]"); + return 1; + } + + Console.WriteLine("Trying to upgrade process file"); + ProcessUpgrader parser = new(processFile); + parser.Upgrade(); + await parser.Write(); + var warnings = parser.GetWarnings(); + foreach (var warning in warnings) + { + Console.WriteLine(warning); + } + + Console.WriteLine(warnings.Any() ? "Process file upgraded with warnings. Review the warnings above and make sure that the process file is still valid." : "Process file upgraded"); + + return 0; + } +} diff --git a/cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj b/cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj new file mode 100644 index 000000000..b7de92cd6 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj @@ -0,0 +1,26 @@ + + + + Exe + net6.0 + altinn_app_upgrade_cli + latest + enable + enable + win-x64;linux-x64;osx-x64 + osx-x64 + aaucli + 0.0.1 + true + false + true + + + + + + + + + + diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs b/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs new file mode 100644 index 000000000..4d7fe96ee --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs @@ -0,0 +1,152 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace altinn_app_upgrade_cli.v7Tov8.CodeRewriters; + +public class TypesRewriter: CSharpSyntaxRewriter +{ + private readonly SemanticModel semanticModel; + private readonly Dictionary fieldDescendantsMapping = new Dictionary() + { + {"Altinn.App.Core.Interface.IAppEvents", SyntaxFactory.IdentifierName("IAppEvents")}, + {"Altinn.App.Core.Interface.IApplication", SyntaxFactory.IdentifierName("IApplicationClient")}, + {"Altinn.App.Core.Interface.IAppResources", SyntaxFactory.IdentifierName("IAppResources")}, + {"Altinn.App.Core.Interface.IAuthentication", SyntaxFactory.IdentifierName("IAuthenticationClient")}, + {"Altinn.App.Core.Interface.IAuthorization", SyntaxFactory.IdentifierName("IAuthorizationClient")}, + {"Altinn.App.Core.Interface.IData", SyntaxFactory.IdentifierName("IDataClient")}, + {"Altinn.App.Core.Interface.IDSF", SyntaxFactory.IdentifierName("IPersonClient")}, + {"Altinn.App.Core.Interface.IER", SyntaxFactory.IdentifierName("IOrganizationClient")}, + {"Altinn.App.Core.Interface.IEvents", SyntaxFactory.IdentifierName("IEventsClient")}, + {"Altinn.App.Core.Interface.IInstance", SyntaxFactory.IdentifierName("IInstanceClient")}, + {"Altinn.App.Core.Interface.IInstanceEvent", SyntaxFactory.IdentifierName("IInstanceEventClient")}, + {"Altinn.App.Core.Interface.IPersonLookup", SyntaxFactory.IdentifierName("IPersonClient")}, + {"Altinn.App.Core.Interface.IPersonRetriever", SyntaxFactory.IdentifierName("IPersonClient")}, + {"Altinn.App.Core.Interface.IPrefill", SyntaxFactory.IdentifierName("IPrefill")}, + {"Altinn.App.Core.Interface.IProcess", SyntaxFactory.IdentifierName("IProcessClient")}, + {"Altinn.App.Core.Interface.IProfile", SyntaxFactory.IdentifierName("IProfileClient")}, + {"Altinn.App.Core.Interface.IRegister", SyntaxFactory.IdentifierName("IAltinnPartyClient")}, + {"Altinn.App.Core.Interface.ISecrets", SyntaxFactory.IdentifierName("ISecretsClient")}, + {"Altinn.App.Core.Interface.ITaskEvents", SyntaxFactory.IdentifierName("ITaskEvents")}, + {"Altinn.App.Core.Interface.IUserTokenProvider", SyntaxFactory.IdentifierName("IUserTokenProvider")} + }; + private readonly IEnumerable statementsToRemove = new List() + { + "app.UseDefaultSecurityHeaders();", + "app.UseRouting();", + "app.UseStaticFiles('/' + applicationId);", + "app.UseAuthentication();", + "app.UseAuthorization();", + "app.UseEndpoints(endpoints", + "app.UseHealthChecks(\"/health\");", + "app.UseAltinnAppCommonConfiguration();" + }; + + public TypesRewriter(SemanticModel semanticModel) + { + this.semanticModel = semanticModel; + } + + public override SyntaxNode? VisitFieldDeclaration(FieldDeclarationSyntax node) + { + return UpdateField(node); + } + + public override SyntaxNode? VisitParameter(ParameterSyntax node) + { + var parameterTypeName = node.Type; + if(parameterTypeName is null) + { + return node; + } + var parameterType = (ITypeSymbol?)semanticModel.GetSymbolInfo(parameterTypeName).Symbol; + if(parameterType?.ToString() != null && fieldDescendantsMapping.TryGetValue(parameterType.ToString()!, out var newType)) + { + var newTypeName = newType.WithLeadingTrivia(parameterTypeName.GetLeadingTrivia()).WithTrailingTrivia(parameterTypeName.GetTrailingTrivia()); + return node.ReplaceNode(parameterTypeName, newTypeName); + } + + return node; + } + + public override SyntaxNode? VisitGlobalStatement(GlobalStatementSyntax node) + { + if (node.Statement is LocalFunctionStatementSyntax localFunctionStatementSyntax) + { + if(localFunctionStatementSyntax.Identifier.Text == "Configure" && !localFunctionStatementSyntax.ParameterList.Parameters.Any() && localFunctionStatementSyntax.Body != null) + { + SyntaxTriviaList leadingTrivia = SyntaxFactory.TriviaList(); + SyntaxTriviaList trailingTrivia = SyntaxFactory.TriviaList(); + var newBody = SyntaxFactory.Block().WithoutLeadingTrivia().WithTrailingTrivia(localFunctionStatementSyntax.Body.GetTrailingTrivia()); + foreach (var childNode in localFunctionStatementSyntax.Body.ChildNodes()) + { + if(childNode is IfStatementSyntax ifStatementSyntax && ifStatementSyntax.Condition.ToString()!="app.Environment.IsDevelopment()") + { + newBody = AddStatementWithTrivia(newBody, ifStatementSyntax); + } + if(childNode is ExpressionStatementSyntax statementSyntax){ + leadingTrivia = statementSyntax.GetLeadingTrivia(); + trailingTrivia = statementSyntax.GetTrailingTrivia(); + if (!ShouldRemoveStatement(statementSyntax)) + { + newBody = AddStatementWithTrivia(newBody, statementSyntax); + } + } + if(childNode is LocalDeclarationStatementSyntax localDeclarationStatement) + { + newBody = AddStatementWithTrivia(newBody, localDeclarationStatement); + } + } + newBody = newBody.AddStatements(SyntaxFactory.ParseStatement("app.UseAltinnAppCommonConfiguration();").WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia)); + return node.ReplaceNode(localFunctionStatementSyntax.Body, newBody); + } + } + + return node; + } + + public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) + { + if (node.Identifier.Text == "FilterAsync" && + node.Parent is ClassDeclarationSyntax { BaseList: not null } classDeclarationSyntax + && classDeclarationSyntax.BaseList.Types.Any(x => x.Type.ToString() == "IProcessExclusiveGateway") + && node.ParameterList.Parameters.All(x => x.Type?.ToString() != "ProcessGatewayInformation")) + { + return node.AddParameterListParameters( + SyntaxFactory.Parameter(SyntaxFactory.Identifier("processGatewayInformation").WithLeadingTrivia(SyntaxFactory.ElasticSpace)).WithType(SyntaxFactory.ParseTypeName("ProcessGatewayInformation").WithLeadingTrivia(SyntaxFactory.ElasticSpace)) + ); + } + + return node; + } + + private FieldDeclarationSyntax UpdateField(FieldDeclarationSyntax node) + { + var variableTypeName = node.Declaration.Type; + var variableType = (ITypeSymbol?)semanticModel.GetSymbolInfo(variableTypeName).Symbol; + if(variableType?.ToString() != null && fieldDescendantsMapping.TryGetValue(variableType.ToString()!, out var newType)) + { + var newTypeName = newType.WithLeadingTrivia(variableTypeName.GetLeadingTrivia()).WithTrailingTrivia(variableTypeName.GetTrailingTrivia()); + node = node.ReplaceNode(variableTypeName, newTypeName); + Console.WriteLine($"Updated field {node.Declaration.Variables.First().Identifier.Text} from {variableType} to {newType}"); + } + return node; + } + + private bool ShouldRemoveStatement(StatementSyntax statementSyntax) + { + foreach (var statementToRemove in statementsToRemove) + { + var s = statementSyntax.ToString(); + if(s == statementToRemove || s.StartsWith(statementToRemove)) + { + return true; + } + } + return false; + } + private static BlockSyntax AddStatementWithTrivia(BlockSyntax block, StatementSyntax statement) + { + return block.AddStatements(statement).WithLeadingTrivia(statement.GetLeadingTrivia()).WithTrailingTrivia(statement.GetTrailingTrivia()); + } +} diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs b/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs new file mode 100644 index 000000000..7295780c4 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs @@ -0,0 +1,91 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace altinn_app_upgrade_cli.v7Tov8.CodeRewriters; + +public class UsingRewriter: CSharpSyntaxRewriter +{ + private const string CommonInterfaceNamespace = "Altinn.App.Core.Interface"; + + private readonly Dictionary usingMappings = new Dictionary() + { + {"IAppEvents", "Altinn.App.Core.Internal.App"}, + {"IApplication", "Altinn.App.Core.Internal.App"}, + {"IAppResources", "Altinn.App.Core.Internal.App"}, + {"IAuthenticationClient", "Altinn.App.Core.Internal.Auth"}, + {"IAuthorizationClient", "Altinn.App.Core.Internal.Auth"}, + {"IDataClient", "Altinn.App.Core.Internal.Data"}, + {"IPersonClient", "Altinn.App.Core.Internal.Registers"}, + {"IOrganizationClient", "Altinn.App.Core.Internal.Registers"}, + {"IEventsClient", "Altinn.App.Core.Internal.Events"}, + {"IInstanceClient", "Altinn.App.Core.Internal.Instances"}, + {"IInstanceEventClient", "Altinn.App.Core.Internal.Instances"}, + {"IPrefill", "Altinn.App.Core.Internal.Prefill"}, + {"IProcessClient", "Altinn.App.Core.Internal.Process"}, + {"IProfileClient", "Altinn.App.Core.Internal.Profile"}, + {"IAltinnPartyClient", "Altinn.App.Core.Internal.Registers"}, + {"ISecretsClient", "Altinn.App.Core.Internal.Secrets"}, + {"ITaskEvents", "Altinn.App.Core.Internal.Process"}, + {"IUserTokenProvider", "Altinn.App.Core.Internal.Auth"}, + }; + + public override SyntaxNode? VisitCompilationUnit(CompilationUnitSyntax node) + { + foreach (var mapping in usingMappings) + { + if (HasFieldOfType(node, mapping.Key)) + { + node = AddUsing(node, mapping.Value); + } + } + + if (ImplementsIProcessExclusiveGateway(node)) + { + node = AddUsing(node, "Altinn.App.Core.Models.Process"); + } + + return RemoveOldUsing(node); + } + + private bool HasFieldOfType(CompilationUnitSyntax node, string typeName) + { + var fieldDecendants = node.DescendantNodes().OfType(); + return fieldDecendants.Any(f => f.Declaration.Type.ToString() == typeName); + } + + private bool ImplementsIProcessExclusiveGateway(CompilationUnitSyntax node) + { + var classDecendants = node.DescendantNodes().OfType(); + return classDecendants.Any(c => c.BaseList?.Types.Any(t => t.Type.ToString() == "IProcessExclusiveGateway") == true); + } + + private CompilationUnitSyntax AddUsing(CompilationUnitSyntax node, string usingString) + { + if (HasUsingDefined(node, usingString)) + { + return node; + } + var usingName = SyntaxFactory.ParseName(usingString); + var usingDirective = SyntaxFactory.UsingDirective(usingName).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed); + return node.AddUsings(usingDirective); + } + + private bool HasUsingDefined(CompilationUnitSyntax node, string usingName) + { + var usingDirectiveSyntaxes = node.DescendantNodes().OfType(); + return usingDirectiveSyntaxes.Any(u => u.Name?.ToString() == usingName); + } + + private CompilationUnitSyntax? RemoveOldUsing(CompilationUnitSyntax node) + { + var usingDirectiveSyntaxes = node.DescendantNodes().OfType(); + var usingDirectiveSyntax = usingDirectiveSyntaxes.FirstOrDefault(u => u.Name?.ToString() == CommonInterfaceNamespace); + if (usingDirectiveSyntax != null) + { + return node.RemoveNode(usingDirectiveSyntax, SyntaxRemoveOptions.KeepNoTrivia); + } + return node; + } + +} diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs b/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs new file mode 100644 index 000000000..3fb65c484 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs @@ -0,0 +1,168 @@ +using System.Text; +using System.Xml; +using System.Xml.Linq; + +namespace altinn_app_upgrade_cli.v7Tov8.ProcessRewriter; + +public class ProcessUpgrader +{ + private XDocument doc; + private readonly string processFile; + private readonly XNamespace newAltinnNs = "http://altinn.no/process"; + private readonly XNamespace origAltinnNs = "http://altinn.no"; + private readonly XNamespace bpmnNs = "http://www.omg.org/spec/BPMN/20100524/MODEL"; + private readonly IList warnings = new List(); + + public ProcessUpgrader(string processFile) + { + this.processFile = processFile; + var xmlString = File.ReadAllText(processFile); + xmlString = xmlString.Replace($"xmlns:altinn=\"{origAltinnNs}\"", $"xmlns:altinn=\"{newAltinnNs}\""); + doc = XDocument.Parse(xmlString); + } + + public void Upgrade() + { + var definitions = doc.Root; + var process = definitions?.Elements().Single(e => e.Name.LocalName == "process"); + var processElements = process?.Elements() ?? Enumerable.Empty(); + foreach (var processElement in processElements) + { + if (processElement.Name.LocalName == "task") + { + UpgradeTask(processElement); + } + else if (processElement.Name.LocalName == "sequenceFlow") + { + UpgradeSequenceFlow(processElement); + } + } + } + + private void UpgradeTask(XElement processElement) + { + var taskTypeAttr = processElement.Attribute(newAltinnNs + "tasktype"); + var taskType = taskTypeAttr?.Value; + if (taskType == null) + { + return; + } + XElement extensionElements = processElement.Element(bpmnNs + "extensionElements") ?? new XElement(bpmnNs + "extensionElements"); + XElement taskExtensionElement = extensionElements.Element(newAltinnNs + "taskExtension") ?? new XElement(newAltinnNs + "taskExtension"); + XElement taskTypeElement = new XElement(newAltinnNs + "taskType"); + taskTypeElement.Value = taskType; + taskExtensionElement.Add(taskTypeElement); + extensionElements.Add(taskExtensionElement); + processElement.Add(extensionElements); + taskTypeAttr?.Remove(); + if (taskType.Equals("confirmation")) + { + AddAction(processElement, "confirm"); + } + } + + private void UpgradeSequenceFlow(XElement processElement) + { + var flowTypeAttr = processElement.Attribute(newAltinnNs + "flowtype"); + flowTypeAttr?.Remove(); + if (flowTypeAttr?.Value != "AbandonCurrentReturnToNext") + { + return; + } + + var sourceRefAttr = processElement.Attribute("sourceRef"); + SetSequenceFlowAsDefaultIfGateway(sourceRefAttr?.Value!, processElement.Attribute("id")?.Value!); + var sourceTask = FollowGatewaysAndGetSourceTask(sourceRefAttr?.Value!); + AddAction(sourceTask, "reject"); + var conditionExpression = processElement.Elements().FirstOrDefault(e => e.Name.LocalName == "conditionExpression"); + if(conditionExpression == null) + { + conditionExpression = new XElement(bpmnNs + "conditionExpression"); + processElement.Add(conditionExpression); + } + conditionExpression.Value = "[\"equals\", [\"gatewayAction\"],\"reject\"]"; + warnings.Add($"SequenceFlow {processElement.Attribute("id")?.Value!} has flowtype {flowTypeAttr.Value} upgrade tool has tried to add reject action to source task. \nPlease verify that process flow is correct and that layoutfiels are updated to use ActionButtons\nRefere to docs.altinn.studio for how actions in v8 work"); + } + + private void SetSequenceFlowAsDefaultIfGateway(string elementRef, string sequenceFlowRef) + { + var sourceElement = doc.Root?.Elements().Single(e => e.Name.LocalName == "process").Elements().Single(e => e.Attribute("id")?.Value == elementRef); + if (sourceElement?.Name.LocalName == "exclusiveGateway") + { + if (sourceElement.Attribute("default") == null) + { + sourceElement.Add(new XAttribute("default", sequenceFlowRef)); + } + else + { + warnings.Add($"Default sequence flow already set for gateway {elementRef}. Process is most likely not correct. Please correct it manually and test it."); + } + } + } + + private XElement FollowGatewaysAndGetSourceTask(string sourceRef) + { + var processElement = doc.Root?.Elements().Single(e => e.Name.LocalName == "process"); + var sourceElement = processElement?.Elements().Single(e => e.Attribute("id")?.Value == sourceRef); + if (sourceElement?.Name.LocalName == "task") + { + return sourceElement; + } + + if (sourceElement?.Name.LocalName == "exclusiveGateway") + { + var incomingSequenceFlow = sourceElement.Elements().Single(e => e.Name.LocalName == "incoming").Value; + var incomingSequenceFlowRef = processElement?.Elements().Single(e => e.Attribute("id")!.Value == incomingSequenceFlow).Attribute("sourceRef")?.Value; + return FollowGatewaysAndGetSourceTask(incomingSequenceFlowRef!); + } + + throw new Exception("Unexpected element type"); + } + + private void AddAction(XElement sourceTask, string actionName) + { + var extensionElements = sourceTask.Element(bpmnNs + "extensionElements"); + if (extensionElements == null) + { + extensionElements = new XElement(bpmnNs + "extensionElements"); + sourceTask.Add(extensionElements); + } + + var taskExtensionElement = extensionElements.Element(newAltinnNs + "taskExtension"); + if (taskExtensionElement == null) + { + taskExtensionElement = new XElement(newAltinnNs + "taskExtension"); + extensionElements.Add(taskExtensionElement); + } + + var actions = taskExtensionElement.Element(newAltinnNs + "actions"); + if (actions == null) + { + actions = new XElement(newAltinnNs + "actions"); + taskExtensionElement.Add(actions); + } + if(actions.Elements().Any(e => e.Value == actionName)) + { + return; + } + var action = new XElement(newAltinnNs + "action"); + action.Value = actionName; + actions.Add(action); + } + + public async Task Write() + { + XmlWriterSettings xws = new XmlWriterSettings(); + xws.Async = true; + xws.OmitXmlDeclaration = false; + xws.Indent = true; + xws.Encoding = Encoding.UTF8; + await using XmlWriter xw = XmlWriter.Create(processFile, xws); + await doc.WriteToAsync(xw, CancellationToken.None); + } + + public IList GetWarnings() + { + return warnings; + } +} diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs b/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs new file mode 100644 index 000000000..2145c4152 --- /dev/null +++ b/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs @@ -0,0 +1,53 @@ +using System.Text; +using System.Xml; +using System.Xml.Linq; + +namespace altinn_app_upgrade_cli.v7Tov8.ProjectRewriters; + +public class ProjectFileRewriter +{ + private XDocument doc; + private readonly string projectFilePath; + private readonly string targetVersion; + + public ProjectFileRewriter(string projectFilePath, string targetVersion = "8.0.0") + { + this.projectFilePath = projectFilePath; + this.targetVersion = targetVersion; + var xmlString = File.ReadAllText(projectFilePath); + doc = XDocument.Parse(xmlString); + } + + public async Task Upgrade() + { + var altinnAppCoreElements = GetAltinnAppCoreElement(); + var altinnAppApiElements = GetAltinnAppApiElement(); + if (altinnAppCoreElements != null && altinnAppApiElements != null) + { + altinnAppCoreElements.ForEach(c => c.Attribute("Version")?.SetValue(targetVersion)); + altinnAppApiElements.ForEach(a => a.Attribute("Version")?.SetValue(targetVersion)); + await Save(); + } + } + + private List? GetAltinnAppCoreElement() + { + return doc.Root?.Elements("ItemGroup").Elements("PackageReference").Where(x => x.Attribute("Include")?.Value == "Altinn.App.Core").ToList(); + } + + private List? GetAltinnAppApiElement() + { + return doc.Root?.Elements("ItemGroup").Elements("PackageReference").Where(x => x.Attribute("Include")?.Value == "Altinn.App.Api").ToList(); + } + + private async Task Save() + { + XmlWriterSettings xws = new XmlWriterSettings(); + xws.Async = true; + xws.OmitXmlDeclaration = true; + xws.Indent = true; + xws.Encoding = Encoding.UTF8; + await using XmlWriter xw = XmlWriter.Create(projectFilePath, xws); + await doc.WriteToAsync(xw, CancellationToken.None); + } +} From b6e47fc64da20c921842f55833face046633ea97 Mon Sep 17 00:00:00 2001 From: Vemund Gaukstad Date: Mon, 21 Aug 2023 15:08:09 +0200 Subject: [PATCH 2/2] rename cli tool and include release pipeline --- .github/workflows/publish-release.yml | 41 +++++++++-- cli-tools/altinn-app-cli/Makefile | 42 +++++++++++ .../Program.cs | 31 +++++--- .../altinn-app-cli.csproj} | 22 +++++- .../v7Tov8/CodeRewriters/TypesRewriter.cs | 2 +- .../v7Tov8/CodeRewriters/UsingRewriter.cs | 2 +- .../v7Tov8/ProcessRewriter/ProcessUpgrader.cs | 2 +- .../v7Tov8/ProjectChecks/ProjectChecks.cs | 71 +++++++++++++++++++ .../ProjectRewriters/ProjectFileRewriter.cs | 2 +- cli-tools/altinn-app-upgrade-cli/Makefile | 21 ------ 10 files changed, 196 insertions(+), 40 deletions(-) create mode 100644 cli-tools/altinn-app-cli/Makefile rename cli-tools/{altinn-app-upgrade-cli => altinn-app-cli}/Program.cs (85%) rename cli-tools/{altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj => altinn-app-cli/altinn-app-cli.csproj} (50%) rename cli-tools/{altinn-app-upgrade-cli => altinn-app-cli}/v7Tov8/CodeRewriters/TypesRewriter.cs (99%) rename cli-tools/{altinn-app-upgrade-cli => altinn-app-cli}/v7Tov8/CodeRewriters/UsingRewriter.cs (98%) rename cli-tools/{altinn-app-upgrade-cli => altinn-app-cli}/v7Tov8/ProcessRewriter/ProcessUpgrader.cs (99%) create mode 100644 cli-tools/altinn-app-cli/v7Tov8/ProjectChecks/ProjectChecks.cs rename cli-tools/{altinn-app-upgrade-cli => altinn-app-cli}/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs (96%) delete mode 100644 cli-tools/altinn-app-upgrade-cli/Makefile diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 31783f348..0686bb30c 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -1,4 +1,4 @@ -name: Pack and publish nugets +name: Pack and publish on: release: @@ -6,7 +6,8 @@ on: - published jobs: - build-pack: + release-nugets: + if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -17,7 +18,6 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: | - 5.0.x 6.0.x - name: Install deps run: | @@ -33,4 +33,37 @@ jobs: dotnet --version - name: Publish run: | - dotnet nuget push src/**/bin/Release/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} \ No newline at end of file + dotnet nuget push src/**/bin/Release/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} + release-upgrade-tool: + if: startsWith(github.ref, 'refs/tags/altinn-app-cli') + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./cli-tools/altinn-app-cli + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install dotnet6 + uses: actions/setup-dotnet@v3 + with: + dotnet-version: | + 6.0.x + - name: Build bundles + run: | + make bundles + - name: Upload files to release + uses: softprops/action-gh-release@v1 + with: + files: | + publish/archives/osx-x64.tar.gz + publish/archives/osx-arm64.tar.gz + publish/archives/linux-x64.tar.gz + publish/archives/linux-arm64.tar.gz + publish/archives/win-x64.zip + publish/archives/osx-x64.tar.gz.sha512 + publish/archives/osx-arm64.tar.gz.sha512 + publish/archives/linux-x64.tar.gz.sha512 + publish/archives/linux-arm64.tar.gz.sha512 + publish/archives/win-x64.zip.sha512 + \ No newline at end of file diff --git a/cli-tools/altinn-app-cli/Makefile b/cli-tools/altinn-app-cli/Makefile new file mode 100644 index 000000000..6cae575a1 --- /dev/null +++ b/cli-tools/altinn-app-cli/Makefile @@ -0,0 +1,42 @@ +# Path: Makefile + +build: + dotnet build + +executable-osx-x64: + dotnet publish -c Release -o publish/osx-x64 -r osx-x64 --self-contained + +executable-osx-arm64: + dotnet publish -c Release -o publish/osx-arm64 -r osx-arm64 --self-contained + +executable-win-x64: + dotnet publish -c Release -o publish/win-x64 -r win-x64 --self-contained + +executable-linux-x64: + dotnet publish -c Release -o publish/linux-x64 -r linux-x64 --self-contained + +executable-linux-arm64: + dotnet publish -c Release -o publish/linux-arm64 -r linux-arm64 --self-contained + +executables: executable-osx-x64 executable-osx-arm64 executable-win-x64 executable-linux-x64 executable-linux-arm64 + +archives: + mkdir -p publish/archives + tar -czvf publish/archives/osx-x64.tar.gz publish/osx-x64/altinn-app-cli + tar -czvf publish/archives/osx-arm64.tar.gz publish/osx-arm64/altinn-app-cli + tar -czvf publish/archives/linux-x64.tar.gz publish/linux-x64/altinn-app-cli + tar -czvf publish/archives/linux-arm64.tar.gz publish/linux-arm64/altinn-app-cli + zip -r publish/archives/win-x64.zip publish/win-x64/altinn-app-cli.exe + +checksums: + sha512sum publish/archives/osx-x64.tar.gz > publish/archives/osx-x64.tar.gz.sha512 + sha512sum publish/archives/osx-arm64.tar.gz > publish/archives/osx-arm64.tar.gz.sha512 + sha512sum publish/archives/linux-x64.tar.gz > publish/archives/linux-x64.tar.gz.sha512 + sha512sum publish/archives/linux-arm64.tar.gz > publish/archives/linux-arm64.tar.gz.sha512 + sha512sum publish/archives/win-x64.zip > publish/archives/win-x64.zip.sha512 + +bundles: executables archives checksums + +clean: + dotnet clean + rm -rf publish/ \ No newline at end of file diff --git a/cli-tools/altinn-app-upgrade-cli/Program.cs b/cli-tools/altinn-app-cli/Program.cs similarity index 85% rename from cli-tools/altinn-app-upgrade-cli/Program.cs rename to cli-tools/altinn-app-cli/Program.cs index 70a08e100..17a257d7a 100644 --- a/cli-tools/altinn-app-upgrade-cli/Program.cs +++ b/cli-tools/altinn-app-cli/Program.cs @@ -1,7 +1,9 @@ using System.CommandLine; -using altinn_app_upgrade_cli.v7Tov8.CodeRewriters; -using altinn_app_upgrade_cli.v7Tov8.ProcessRewriter; -using altinn_app_upgrade_cli.v7Tov8.ProjectRewriters; +using System.Reflection; +using altinn_app_cli.v7Tov8.CodeRewriters; +using altinn_app_cli.v7Tov8.ProcessRewriter; +using altinn_app_cli.v7Tov8.ProjectChecks; +using altinn_app_cli.v7Tov8.ProjectRewriters; using Microsoft.Build.Locator; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.MSBuild; @@ -20,8 +22,8 @@ static async Task Main(string[] args) var skipCsprojUpgradeOption = new Option(name: "--skip-csproj-upgrade", description: "Skip csproj file upgrade", getDefaultValue: () => false); var skipCodeUpgradeOption = new Option(name: "--skip-code-upgrade", description: "Skip code upgrade", getDefaultValue: () => false); var skipProcessUpgradeOption = new Option(name: "--skip-process-upgrade", description: "Skip process file upgrade", getDefaultValue: () => false); - var rootCommand = new RootCommand("Sample app for System.CommandLine"); - var upgradeCommand = new Command("upgrade", "Upgrade an app") + var rootCommand = new RootCommand("Command line interface for working with Altinn 3 Applications"); + var upgradeCommand = new Command("upgrade", "Upgrade an app from v7 to v8") { projectFolderOption, projectFileOption, @@ -32,6 +34,8 @@ static async Task Main(string[] args) skipProcessUpgradeOption, }; rootCommand.AddCommand(upgradeCommand); + var versionCommand = new Command("version", "Print version of altinn-app-cli"); + rootCommand.AddCommand(versionCommand); upgradeCommand.SetHandler(async (projectFolder, projectFile, processFile, targetVersion, skipCodeUpgrade, skipProcessUpgrade, skipCsprojUpgrade) => { @@ -42,7 +46,7 @@ static async Task Main(string[] args) if (File.Exists(projectFolder)) { - Console.WriteLine($"Project folder {projectFolder} does not exist. Please supply location of project with --project-folder [path/to/project]"); + Console.WriteLine($"Project folder {projectFolder} does not exist. Please supply location of project with --folder [path/to/project]"); returnCode = 1; return; } @@ -50,7 +54,7 @@ static async Task Main(string[] args) FileAttributes attr = File.GetAttributes(projectFolder); if ((attr & FileAttributes.Directory) != FileAttributes.Directory) { - Console.WriteLine($"Project folder {projectFolder} is a file. Please supply location of project with --project-folder [path/to/project]"); + Console.WriteLine($"Project folder {projectFolder} is a file. Please supply location of project with --folder [path/to/project]"); returnCode = 1; return; } @@ -66,6 +70,13 @@ static async Task Main(string[] args) processFile = Path.Combine(projectFolder, processFile); } + var projectChecks = new ProjectChecks(projectFile); + if (!projectChecks.SupportedSourceVersion()) + { + Console.WriteLine($"Version(s) in project file {projectFile} is not supported. Please upgrade to version 7.0.0 or higher."); + returnCode = 2; + return; + } if (!skipCsprojUpgrade) { returnCode = await UpgradeNugetVersions(projectFile, targetVersion); @@ -91,7 +102,11 @@ static async Task Main(string[] args) } }, projectFolderOption, projectFileOption, processFileOption, targetVersionOption, skipCodeUpgradeOption, skipProcessUpgradeOption, skipCsprojUpgradeOption); - + versionCommand.SetHandler(() => + { + var version = Assembly.GetEntryAssembly()?.GetCustomAttribute()?.InformationalVersion ?? "Unknown"; + Console.WriteLine($"altinn-app-cli v{version}"); + }); await rootCommand.InvokeAsync(args); return returnCode; } diff --git a/cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj b/cli-tools/altinn-app-cli/altinn-app-cli.csproj similarity index 50% rename from cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj rename to cli-tools/altinn-app-cli/altinn-app-cli.csproj index b7de92cd6..4798b1dd1 100644 --- a/cli-tools/altinn-app-upgrade-cli/altinn-app-upgrade-cli.csproj +++ b/cli-tools/altinn-app-cli/altinn-app-cli.csproj @@ -3,14 +3,13 @@ Exe net6.0 - altinn_app_upgrade_cli + altinn_app_cli latest enable enable win-x64;linux-x64;osx-x64 osx-x64 - aaucli - 0.0.1 + altinn-app-cli true false true @@ -23,4 +22,21 @@ + + + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) + preview + altinn-app-cli + true + 10.0 + + + + + $(MinVerMajor).$(MinVerMinor).$(MinVerPatch) + + diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs b/cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/TypesRewriter.cs similarity index 99% rename from cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs rename to cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/TypesRewriter.cs index 4d7fe96ee..8e7836248 100644 --- a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/TypesRewriter.cs +++ b/cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/TypesRewriter.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace altinn_app_upgrade_cli.v7Tov8.CodeRewriters; +namespace altinn_app_cli.v7Tov8.CodeRewriters; public class TypesRewriter: CSharpSyntaxRewriter { diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs b/cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/UsingRewriter.cs similarity index 98% rename from cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs rename to cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/UsingRewriter.cs index 7295780c4..1d692a3a7 100644 --- a/cli-tools/altinn-app-upgrade-cli/v7Tov8/CodeRewriters/UsingRewriter.cs +++ b/cli-tools/altinn-app-cli/v7Tov8/CodeRewriters/UsingRewriter.cs @@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace altinn_app_upgrade_cli.v7Tov8.CodeRewriters; +namespace altinn_app_cli.v7Tov8.CodeRewriters; public class UsingRewriter: CSharpSyntaxRewriter { diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs b/cli-tools/altinn-app-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs similarity index 99% rename from cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs rename to cli-tools/altinn-app-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs index 3fb65c484..e23be8615 100644 --- a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs +++ b/cli-tools/altinn-app-cli/v7Tov8/ProcessRewriter/ProcessUpgrader.cs @@ -2,7 +2,7 @@ using System.Xml; using System.Xml.Linq; -namespace altinn_app_upgrade_cli.v7Tov8.ProcessRewriter; +namespace altinn_app_cli.v7Tov8.ProcessRewriter; public class ProcessUpgrader { diff --git a/cli-tools/altinn-app-cli/v7Tov8/ProjectChecks/ProjectChecks.cs b/cli-tools/altinn-app-cli/v7Tov8/ProjectChecks/ProjectChecks.cs new file mode 100644 index 000000000..4c4ddc73b --- /dev/null +++ b/cli-tools/altinn-app-cli/v7Tov8/ProjectChecks/ProjectChecks.cs @@ -0,0 +1,71 @@ +using System.Xml.Linq; + +namespace altinn_app_cli.v7Tov8.ProjectChecks; + +public class ProjectChecks +{ + private XDocument doc; + + public ProjectChecks(string projectFilePath) + { + var xmlString = File.ReadAllText(projectFilePath); + doc = XDocument.Parse(xmlString); + } + + public bool SupportedSourceVersion() + { + var altinnAppCoreElements = GetAltinnAppCoreElement(); + var altinnAppApiElements = GetAltinnAppApiElement(); + if (altinnAppCoreElements == null || altinnAppApiElements == null) + { + return false; + } + + if (altinnAppApiElements.Select(apiElement => apiElement.Attribute("Version")?.Value).Any(altinnAppApiVersion => !SupportedSourceVersion(altinnAppApiVersion))) + { + return false; + } + + return altinnAppCoreElements.Select(coreElement => coreElement.Attribute("Version")?.Value).All(altinnAppCoreVersion => SupportedSourceVersion(altinnAppCoreVersion)); + + } + + private List? GetAltinnAppCoreElement() + { + return doc.Root?.Elements("ItemGroup").Elements("PackageReference").Where(x => x.Attribute("Include")?.Value == "Altinn.App.Core").ToList(); + } + + private List? GetAltinnAppApiElement() + { + return doc.Root?.Elements("ItemGroup").Elements("PackageReference").Where(x => x.Attribute("Include")?.Value == "Altinn.App.Api").ToList(); + } + + /// + /// Check that version is >=7.0.0 + /// + /// + /// + private bool SupportedSourceVersion(string? version) + { + if (version == null) + { + return false; + } + + var versionParts = version.Split('.'); + if (versionParts.Length < 3) + { + return false; + } + + if (int.TryParse(versionParts[0], out int major)) + { + if (major >= 7) + { + return true; + } + } + + return false; + } +} diff --git a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs b/cli-tools/altinn-app-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs similarity index 96% rename from cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs rename to cli-tools/altinn-app-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs index 2145c4152..11def034d 100644 --- a/cli-tools/altinn-app-upgrade-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs +++ b/cli-tools/altinn-app-cli/v7Tov8/ProjectRewriters/ProjectFileRewriter.cs @@ -2,7 +2,7 @@ using System.Xml; using System.Xml.Linq; -namespace altinn_app_upgrade_cli.v7Tov8.ProjectRewriters; +namespace altinn_app_cli.v7Tov8.ProjectRewriters; public class ProjectFileRewriter { diff --git a/cli-tools/altinn-app-upgrade-cli/Makefile b/cli-tools/altinn-app-upgrade-cli/Makefile deleted file mode 100644 index 11b5ab955..000000000 --- a/cli-tools/altinn-app-upgrade-cli/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Path: Makefile - -build: - dotnet build - -executable-osx-x64: - dotnet publish -c Release -o publish/osx-x64 -r osx-x64 --self-contained - -executable-osx-arm64: - dotnet publish -c Release -o publish/osx-arm64 -r osx-arm64 - -executable-win-x64: - dotnet publish -c Release -o publish/win-x64 -r win-x64 - -executable-linux-x64: - dotnet publish -c Release -o publish/linux-x64 -r linux-x64 - -executable-linux-arm64: - dotnet publish -c Release -o publish/linux-arm64 -r linux-arm64 - -executables: executable-osx-x64 executable-osx-arm64 executable-win-x64 executable-linux-x64 executable-linux-arm64 \ No newline at end of file