Exemplo n.º 1
0
        public async Task BuildDoesNotRequireRegistry()
        {
            await DockerAssert.DeleteDockerImagesAsync(output, "test-project");

            var projectName = "single-project";
            var environment = "production";

            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            try
            {
                await BuildHost.ExecuteBuildAsync(outputContext, application, environment, interactive : false);

                await DockerAssert.AssertImageExistsAsync(output, "test-project");
            }
            finally
            {
                await DockerAssert.DeleteDockerImagesAsync(output, "test-project");
            }
        }
Exemplo n.º 2
0
        public async Task FixAsync(string packagesDirectory, ILogger logger)
        {
            string nlogDirectoryPath = Path.Combine(packagesDirectory, "NLog.3.2.0.0");

            var nlogDirectory = new DirectoryInfo(nlogDirectoryPath);

            if (nlogDirectory.Exists)
            {
                var targetDir = new DirectoryInfo(Path.Combine(packagesDirectory, "NLog.3.2.0"));

                if (!targetDir.Exists)
                {
                    logger.WriteDebug($"Copying NLog from '{nlogDirectory.FullName}' to '{targetDir.FullName}'");
                    ExitCode exitCode = await DirectoryCopy.CopyAsync(
                        nlogDirectory.FullName,
                        targetDir.FullName,
                        logger,
                        new PathLookupSpecification());

                    if (!exitCode.IsSuccess)
                    {
                        logger.WriteWarning("Failed to copy NLog NuGet package");
                    }
                }
            }
        }
Exemplo n.º 3
0
        public async Task GenerateWorksWithoutRegistry()
        {
            await DockerAssert.DeleteDockerImagesAsync(output, "test-project");

            var projectName = "single-project";
            var environment = "production";

            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));

            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            try
            {
                await GenerateHost.ExecuteGenerateAsync(outputContext, application, environment, interactive : false);

                // name of application is the folder
                var content         = File.ReadAllText(Path.Combine(tempDirectory.DirectoryPath, $"{projectName}-generate-{environment}.yaml"));
                var expectedContent = File.ReadAllText($"testassets/generate/{projectName}-noregistry.yaml");

                Assert.Equal(expectedContent.NormalizeNewLines(), content.NormalizeNewLines());

                await DockerAssert.AssertImageExistsAsync(output, "test-project");
            }
            finally
            {
                await DockerAssert.DeleteDockerImagesAsync(output, "test-project");
            }
        }
Exemplo n.º 4
0
        internal static TempDirectory CopyTestProjectDirectory(string projectName)
        {
            var temp = TempDirectory.Create();

            DirectoryCopy.Copy(GetTestProjectDirectory(projectName).FullName, temp.DirectoryPath);
            return(temp);
        }
Exemplo n.º 5
0
        public async Task SingleProjectGenerateTest()
        {
            await DockerAssert.DeleteDockerImagesAsync(output, "test/test-project");

            var projectName = "single-project";
            var environment = "production";

            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));

            var application = ConfigFactory.FromFile(projectFile);

            // Need to add docker registry for generate
            application.Registry = "test";

            try
            {
                await GenerateHost.ExecuteGenerateAsync(new OutputContext(sink, Verbosity.Debug), application, environment, interactive : false);

                // name of application is the folder
                var content         = File.ReadAllText(Path.Combine(tempDirectory.DirectoryPath, $"{projectName}-generate-{environment}.yaml"));
                var expectedContent = File.ReadAllText($"testassets/generate/{projectName}.yaml");

                Assert.Equal(expectedContent, content);
                await DockerAssert.AssertImageExistsAsync(output, "test/test-project");
            }
            finally
            {
                await DockerAssert.DeleteDockerImagesAsync(output, "test/test-project");
            }
        }
Exemplo n.º 6
0
        private async Task <BootstrapStartOptions> StartWithDebuggerAsync([NotNull] string[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            string baseDir = VcsPathHelper.FindVcsRootPath(AppDomain.CurrentDomain.BaseDirectory);

            var tempDirectory = new DirectoryInfo(Path.Combine(
                                                      Path.GetTempPath(),
                                                      $"{DefaultPaths.TempPathPrefix}_Boot_Debug",
                                                      DateTime.Now.ToString("yyyyMMddHHmmssfff")));

            tempDirectory.EnsureExists();

            WriteDebug($"Using temp directory '{tempDirectory}'");

            await DirectoryCopy.CopyAsync(baseDir, tempDirectory.FullName);

            Environment.SetEnvironmentVariable(WellKnownVariables.BranchNameVersionOverrideEnabled, "true");
            Environment.SetEnvironmentVariable(WellKnownVariables.VariableOverrideEnabled, "true");

            var bootstrapStartOptions = new BootstrapStartOptions(
                tempDirectory.FullName,
                true,
                "refs/heads/develop/12.34.56");

            WriteDebug("Starting with debugger attached");

            return(bootstrapStartOptions);
        }
Exemplo n.º 7
0
        public static TempDirectory CopyTestProjectDirectory(string projectName)
        {
            var temp = TempDirectory.Create(preferUserDirectoryOnMacOS: true);

            DirectoryCopy.Copy(GetTestProjectDirectory(projectName).FullName, temp.DirectoryPath);

            // We need to hijack any P2P references to Tye libraries.
            // Test projects must use $(TyeLibrariesPath) to find their references.
            var libraryPath = Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "src");

            if (!libraryPath.EndsWith(Path.DirectorySeparatorChar))
            {
                libraryPath += Path.DirectorySeparatorChar;
            }

            File.WriteAllText(
                Path.Combine(temp.DirectoryPath, "Directory.Build.props"),
                $@"
<Project>
  <PropertyGroup>
    <TyeLibrariesPath>{libraryPath}</TyeLibrariesPath>
  </PropertyGroup>
</Project>");

            return(temp);
        }
Exemplo n.º 8
0
        public async Task FrontendBackendBuildTest()
        {
            await DockerAssert.DeleteDockerImagesAsync(output, "test/backend");

            await DockerAssert.DeleteDockerImagesAsync(output, "test/frontend");

            var projectName = "frontend-backend";
            var environment = "production";

            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));

            var application = ConfigFactory.FromFile(projectFile);

            application.Registry = "test";

            try
            {
                await BuildHost.ExecuteBuildAsync(new OutputContext(sink, Verbosity.Debug), application, environment, interactive : false);

                await DockerAssert.AssertImageExistsAsync(output, "test/backend");

                await DockerAssert.AssertImageExistsAsync(output, "test/frontend");
            }
            finally
            {
                await DockerAssert.DeleteDockerImagesAsync(output, "test/backend");

                await DockerAssert.DeleteDockerImagesAsync(output, "test/frontend");
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Executes directory transfer.
        /// </summary>
        /// <exception cref="DirectoryTransferException"/>
        public override void Run()
        {
            ct.ThrowIfCancellationRequested();

            try
            {
                var copy = new DirectoryCopy(this);
                copy.ProgressChange += OnCopyProgress;

                copy.Run();

                if (Args.Settings == TransferSettings.DeleteOriginal)
                {
                    Args.From.Delete(true);
                }

                OnProgressChange(100f);
            }
            catch (Exception e) when(e is IOException | e is SecurityException | e is UnauthorizedAccessException)
            {
                throw new DirectoryTransferException(Args, e);
            }
            //Delete(true) can fail despite deleting some files. Therefore rollback could be as time consuming as the actual task.
            //Consequently I decided to leave the rollback on user. (Should be easy once TransferSettings.Overwrite is implemented.)
        }
Exemplo n.º 10
0
        public async Task MultiProjectPurgeTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "multi-project"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));
            var tyeDir        = new DirectoryInfo(Path.Combine(tempDirectory.DirectoryPath, ".tye"));
            var outputContext = new OutputContext(_sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            var host = new TyeHost(application.ToHostingApplication(), Array.Empty <string>())
            {
                Sink = _sink,
            };

            try
            {
                await TestHelpers.StartHostAndWaitForReplicasToStart(host);

                try
                {
                    var pids       = GetAllAppPids(host.Application);
                    var containers = GetAllContainerIds(host.Application);

                    Assert.True(Directory.Exists(tyeDir.FullName));
                    Assert.Subset(new HashSet <int>(GetAllPids()), new HashSet <int>(pids));
                    Assert.Subset(new HashSet <string>(await DockerAssert.GetRunningContainersIdsAsync(_output)),
                                  new HashSet <string>(containers));

                    await TestHelpers.PurgeHostAndWaitForGivenReplicasToStop(host,
                                                                             GetAllReplicasNames(host.Application));

                    var runningPids = new HashSet <int>(GetAllPids());
                    Assert.True(pids.All(pid => !runningPids.Contains(pid)));
                    var runningContainers =
                        new HashSet <string>(await DockerAssert.GetRunningContainersIdsAsync(_output));
                    Assert.True(containers.All(c => !runningContainers.Contains(c)));
                }
                finally
                {
                    await host.StopAsync();
                }
            }
            finally
            {
                host.Dispose();
                Assert.False(Directory.Exists(tyeDir.FullName));
            }
        }
Exemplo n.º 11
0
        public override bool Execute()
        {
            // Debugger.Launch();
            Log.LogMessage(MessageImportance.High, "Preparing Electron files...");

            string aspCoreProjectPath = ProjectDir;

            Log.LogMessage(MessageImportance.High, $"aspCoreProjectPath {aspCoreProjectPath}");

            string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");

            if (Directory.Exists(tempPath) == false)
            {
                Directory.CreateDirectory(tempPath);
            }

            DeployEmbeddedElectronFiles.Do(tempPath);

            var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

            Log.LogMessage(MessageImportance.High, "node_modules missing in: " + nodeModulesDirPath);
            Log.LogMessage(MessageImportance.High, "Start npm install...");

            ProcessHelper.CmdExecute(Log, "npm install", tempPath);
            Log.LogMessage(MessageImportance.High, "ElectronHostHook handling started...");

            string electronhosthookDir = Path.Combine(aspCoreProjectPath, "ElectronHostHook");

            if (Directory.Exists(electronhosthookDir))
            {
                string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                {
                    "node_modules"
                });

                Log.LogMessage(MessageImportance.High, "Start npm install for typescript & hosthooks...");
                ProcessHelper.CmdExecute(Log, "npm install", hosthookDir);

                // ToDo: Not sure if this runs under linux/macos
                ProcessHelper.CmdExecute(Log, @"npx tsc -p ../../ElectronHostHook", tempPath);
            }

            return(true);
        }
Exemplo n.º 12
0
        public void SingleProjectInitTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "single-project", "test-project"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            File.Delete(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "test-project.csproj"));

            var(content, _) = InitHost.CreateTyeFileContent(projectFile, force: false);
            var expectedContent = File.ReadAllText("testassets/init/single-project.yaml");

            output.WriteLine(content);

            Assert.Equal(expectedContent.NormalizeNewLines(), content.NormalizeNewLines());
        }
Exemplo n.º 13
0
        public void FrontendBackendTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "frontend-backend"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            // delete already present yaml
            File.Delete(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "frontend-backend.sln"));

            var(content, _) = InitHost.CreateTyeFileContent(projectFile, force: false);
            var expectedContent = File.ReadAllText("testassets/init/frontend-backend.yaml");

            output.WriteLine(content);

            Assert.Equal(expectedContent.NormalizeNewLines(), content.NormalizeNewLines());
        }
Exemplo n.º 14
0
        public async Task FrontendBackendRunTestWithDocker()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "frontend-backend"));

            using var tempDirectory = TempDirectory.Create(preferUserDirectoryOnMacOS: true);
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            using var host = new TyeHost(application.ToHostingApplication(), new[] { "--docker" })
                  {
                      Sink = sink,
                  };

            await host.StartAsync();

            try
            {
                // Make sure we're runningn containers
                Assert.True(host.Application.Services.All(s => s.Value.Description.RunInfo is DockerRunInfo));

                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
                    AllowAutoRedirect = false
                };

                var client = new HttpClient(new RetryHandler(handler));

                var dashboardUri = new Uri(host.DashboardWebApplication !.Addresses.First());

                await CheckServiceIsUp(host.Application, client, "backend", dashboardUri, timeout : TimeSpan.FromSeconds(60));
                await CheckServiceIsUp(host.Application, client, "frontend", dashboardUri, timeout : TimeSpan.FromSeconds(60));
            }
            finally
            {
                await host.StopAsync();
            }
        }
Exemplo n.º 15
0
        public async Task NullDebugTargetsDoesNotThrow()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "single-project", "test-project"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "test-project.csproj"));

            // Debug targets can be null if not specified, so make sure calling host.Start does not throw.
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            using var host = new TyeHost(application.ToHostingApplication(), Array.Empty <string>())
                  {
                      Sink = sink,
                  };

            await host.StartAsync();

            await host.StopAsync();
        }
Exemplo n.º 16
0
        public async Task FrontendBackendRunTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "frontend-backend"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            using var host = new TyeHost(application.ToHostingApplication(), Array.Empty <string>())
                  {
                      Sink = sink,
                  };

            await host.StartAsync();

            try
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
                    AllowAutoRedirect = false
                };

                var client = new HttpClient(new RetryHandler(handler));

                var dashboardUri = new Uri(host.DashboardWebApplication !.Addresses.First());

                await CheckServiceIsUp(host.Application, client, "backend", dashboardUri);
                await CheckServiceIsUp(host.Application, client, "frontend", dashboardUri);
            }
            finally
            {
                await host.StopAsync();
            }
        }
Exemplo n.º 17
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Build Electron Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                //This version will be shared between the dotnet publish and electron-builder commands
                string version = null;
                if (parser.Arguments.ContainsKey(_paramVersion))
                {
                    version = parser.Arguments[_paramVersion][0];
                }

                if (!parser.Arguments.ContainsKey(_paramTarget) || parser.Arguments[_paramTarget].Length == 0)
                {
                    Console.WriteLine($"Error: missing '{_paramTarget}' argument.");
                    Console.WriteLine(COMMAND_ARGUMENTS);
                    return false;
                }

                var desiredPlatform = parser.Arguments[_paramTarget][0];
                string specifiedFromCustom = string.Empty;
                if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
                {
                    specifiedFromCustom = parser.Arguments[_paramTarget][1];
                }

                string configuration = "Release";
                if (parser.Arguments.ContainsKey(_paramDotNetConfig))
                {
                    configuration = parser.Arguments[_paramDotNetConfig][0];
                }

                var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}...");

                string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform);

                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }
                else
                {
                    Directory.Delete(tempPath, true);
                    Directory.CreateDirectory(tempPath);
                }


                Console.WriteLine("Executing dotnet publish in this directory: " + tempPath);

                string tempBinPath = Path.Combine(tempPath, "bin");

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration...");

                var dotNetPublishFlags = GetDotNetPublishFlags(parser, "false", "false");

                var project = string.Empty;
                if (parser.Arguments.ContainsKey(_paramDotNetProject))
                {
                    project = parser.Arguments[_paramDotNetProject][0];
                }

                var command =
                    $"dotnet publish {project} -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))}";

                // add any additional dotnet flags
                var dotnetFlags = GetDotNetArgs(parser);
                if (dotnetFlags.Any())
                {
                    command += " " + string.Join(" ", dotnetFlags);
                }

                // output the command
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(command);
                Console.ResetColor();

                var resultCode = ProcessHelper.CmdExecute(command, Directory.GetCurrentDirectory());

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);

                if (parser.Arguments.ContainsKey(_paramPackageJson))
                {
                    Console.WriteLine("Copying custom package.json.");

                    File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true);
                }

                var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                if (!Directory.Exists(checkForNodeModulesDirPath) || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
                {
                    Console.WriteLine("Start npm install...");
                    ProcessHelper.CmdExecute("npm install --production", tempPath);
                }

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
                }

                Console.WriteLine("Build Electron Desktop Application...");

                // Specifying an absolute path supercedes a relative path
                string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop");
                if (parser.Arguments.ContainsKey(_paramAbsoluteOutput))
                {
                    buildPath = parser.Arguments[_paramAbsoluteOutput][0];
                }
                else if (parser.Arguments.ContainsKey(_paramOutputDirectory))
                {
                    buildPath = Path.Combine(Directory.GetCurrentDirectory(), parser.Arguments[_paramOutputDirectory][0]);
                }

                Console.WriteLine("Executing electron magic in this directory: " + buildPath);


                string electronArch = "x64";

                if (platformInfo.NetCorePublishRid == "osx-arm64") //Apple Silicon Mac
                {
                    electronArch = "arm64";
                }

                if (parser.Arguments.ContainsKey(_paramElectronArch))
                {
                    electronArch = parser.Arguments[_paramElectronArch][0];
                }

                var electronVersion = "";
                if (parser.Arguments.ContainsKey(_paramElectronVersion))
                {
                    electronVersion = parser.Arguments[_paramElectronVersion][0];
                }
                else
                {
                    //try getting version from project
                    foreach (var projectFile in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj"))
                    {
                        var projectXML = File.ReadAllText(projectFile);
                        var match = Regex.Match(projectXML, @"<PackageReference\s+Include=""h5\.ElectronNET\.API""\s+Version=""([0-9\.]+)""\s+\/>");
                        if (match.Success)
                        {
                            var candidate = match.Groups[1].Value;
                            var majorMinorRevision = string.Join(".", candidate.Split(new char[] { '.' }).Take(3));
                            electronVersion = majorMinorRevision;
                            Console.WriteLine($"Found electron version {majorMinorRevision} in project file {projectFile}");
                            break;
                        }
                    }
                }

                if (string.IsNullOrWhiteSpace(electronVersion))
                {
                    electronVersion = _defaultElectronVersion;
                }


                string electronParams = "";
                if (parser.Arguments.ContainsKey(_paramElectronParams))
                {
                    electronParams = parser.Arguments[_paramElectronParams][0];
                }

                // ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :)
                Console.WriteLine("Create electron-builder configuration file...");

                string manifestFileName = "electron.manifest.json";

                if (parser.Arguments.ContainsKey(_manifest))
                {
                    manifestFileName = parser.Arguments[_manifest].First();
                }

                ProcessHelper.CmdExecute(
                    string.IsNullOrWhiteSpace(version)
                        ? $"node build-helper.js {manifestFileName}"
                        : $"node build-helper.js {manifestFileName} {version}", tempPath);

                Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
                ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion={electronVersion} {electronParams}", tempPath);

                Console.WriteLine("... done");

                return true;
            }));
        }
Exemplo n.º 18
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Start Electron Desktop Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                string aspCoreProjectPath = "";

                if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
                {
                    string projectPath = parser.Arguments[_aspCoreProjectPath].First();
                    if (Directory.Exists(projectPath))
                    {
                        aspCoreProjectPath = projectPath;
                    }
                }
                else
                {
                    aspCoreProjectPath = Directory.GetCurrentDirectory();
                }

                string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");
                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }

                string tempBinPath = Path.Combine(tempPath, "bin");
                var resultCode = 0;

                string publishReadyToRun = "/p:PublishReadyToRun=";
                if (parser.Arguments.ContainsKey(_paramPublishReadyToRun))
                {
                    publishReadyToRun += parser.Arguments[_paramPublishReadyToRun][0];
                }
                else
                {
                    publishReadyToRun += "true";
                }

                string publishSingleFile = "/p:PublishSingleFile=";
                if (parser.Arguments.ContainsKey(_paramPublishSingleFile))
                {
                    publishSingleFile += parser.Arguments[_paramPublishSingleFile][0];
                }
                else
                {
                    publishSingleFile += "true";
                }

                // If target is specified as a command line argument, use it.
                // Format is the same as the build command.
                // If target is not specified, autodetect it.
                var platformInfo = GetTargetPlatformInformation.Do(string.Empty, string.Empty);
                if (parser.Arguments.ContainsKey(_paramTarget))
                {
                    var desiredPlatform = parser.Arguments[_paramTarget][0];
                    string specifiedFromCustom = string.Empty;
                    if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
                    {
                        specifiedFromCustom = parser.Arguments[_paramTarget][1];
                    }
                    platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);
                }

                string configuration = "Debug";
                if (parser.Arguments.ContainsKey(_paramDotNetConfig))
                {
                    configuration = parser.Arguments[_paramDotNetConfig][0];
                }

                if (parser != null && !parser.Arguments.ContainsKey("watch"))
                {
                    resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {publishReadyToRun} {publishSingleFile} --no-self-contained", aspCoreProjectPath);
                }

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);

                var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                Console.WriteLine("node_modules missing in: " + nodeModulesDirPath);

                Console.WriteLine("Start npm install...");
                ProcessHelper.CmdExecute("npm install", tempPath);

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for typescript & hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p ../../ElectronHostHook", tempPath);
                }

                string arguments = "";

                if (parser.Arguments.ContainsKey(_arguments))
                {
                    arguments = string.Join(' ', parser.Arguments[_arguments]);
                }

                if (parser.Arguments.ContainsKey(_manifest))
                {
                    arguments += " --manifest=" + parser.Arguments[_manifest].First();
                }

                if (parser.Arguments.ContainsKey(_clearCache))
                {
                    arguments += " --clear-cache=true";
                }

                if (parser.Arguments.ContainsKey("watch"))
                {
                    arguments += " --watch=true";
                }

                string path = Path.Combine(tempPath, "node_modules", ".bin");
                bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                if (isWindows)
                {
                    Console.WriteLine("Invoke electron.cmd - in dir: " + path);
                    ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
                }
                else
                {
                    Console.WriteLine("Invoke electron - in dir: " + path);
                    ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
                }

                return true;
            }));
        }
Exemplo n.º 19
0
        public async Task SingleProjectRunTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "single-project", "test-project"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "test-project.csproj"));
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            using var host = new TyeHost(application.ToHostingApplication(), Array.Empty <string>())
                  {
                      Sink = sink,
                  };

            await host.StartAsync();

            try
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
                    AllowAutoRedirect = false
                };

                var client = new HttpClient(new RetryHandler(handler));

                // Make sure dashboard and applications are up.
                // Dashboard should be hosted in same process.
                var dashboardUri    = new Uri(host.DashboardWebApplication !.Addresses.First());
                var dashboardString = await client.GetStringAsync($"{dashboardUri}api/v1/services/test-project");

                var service           = JsonSerializer.Deserialize <V1Service>(dashboardString, _options);
                var binding           = service.Description !.Bindings.Where(b => b.Protocol == "http").Single();
                var uriBackendProcess = new Uri($"{binding.Protocol}://localhost:{binding.Port}");

                // This isn't reliable right now because micronetes only guarantees the process starts, not that
                // that kestrel started.
                try
                {
                    var appResponse = await client.GetAsync(uriBackendProcess);

                    Assert.Equal(HttpStatusCode.OK, appResponse.StatusCode);
                }
                finally
                {
                    // If we failed, there's a good chance the service isn't running. Let's get the logs either way and put
                    // them in the output.
                    var request  = new HttpRequestMessage(HttpMethod.Get, new Uri(dashboardUri, $"/api/v1/logs/{service.Description.Name}"));
                    var response = await client.SendAsync(request);

                    var text = await response.Content.ReadAsStringAsync();

                    output.WriteLine($"Logs for service: {service.Description.Name}");
                    output.WriteLine(text);
                }
            }
            finally
            {
                await host.StopAsync();
            }
        }
Exemplo n.º 20
0
        public async Task IngressRunTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "apps-with-ingress"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile   = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml"));
            var outputContext = new OutputContext(sink, Verbosity.Debug);
            var application   = await ApplicationFactory.CreateAsync(outputContext, projectFile);

            using var host = new TyeHost(application.ToHostingApplication(), Array.Empty <string>())
                  {
                      Sink = sink,
                  };

            var handler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
                AllowAutoRedirect = false
            };

            using var client = new HttpClient(new RetryHandler(handler));
            await host.StartAsync();

            var serviceApi = new Uri(host.DashboardWebApplication !.Addresses.First());

            try
            {
                var ingressService = await client.GetStringAsync($"{serviceApi}api/v1/services/ingress");

                var service    = JsonSerializer.Deserialize <V1Service>(ingressService, _options);
                var binding    = service.Description !.Bindings.Single();
                var ingressUri = $"http://localhost:{binding.Port}";

                var responseA = await client.GetAsync(ingressUri + "/A");

                var responseB = await client.GetAsync(ingressUri + "/B");

                Assert.StartsWith("Hello from Application A", await responseA.Content.ReadAsStringAsync());
                Assert.StartsWith("Hello from Application B", await responseB.Content.ReadAsStringAsync());

                var requestA = new HttpRequestMessage(HttpMethod.Get, ingressUri);
                requestA.Headers.Host = "a.example.com";
                var requestB = new HttpRequestMessage(HttpMethod.Get, ingressUri);
                requestB.Headers.Host = "b.example.com";

                responseA = await client.SendAsync(requestA);

                responseB = await client.SendAsync(requestB);

                Assert.StartsWith("Hello from Application A", await responseA.Content.ReadAsStringAsync());
                Assert.StartsWith("Hello from Application B", await responseB.Content.ReadAsStringAsync());
            }
            finally
            {
                // If we failed, there's a good chance the service isn't running. Let's get the logs either way and put
                // them in the output.
                foreach (var s in host.Application.Services.Values)
                {
                    var request  = new HttpRequestMessage(HttpMethod.Get, new Uri(serviceApi, $"/api/v1/logs/{s.Description.Name}"));
                    var response = await client.SendAsync(request);

                    var text = await response.Content.ReadAsStringAsync();

                    output.WriteLine($"Logs for service: {s.Description.Name}");
                    output.WriteLine(text);
                }

                await host.StopAsync();
            }
        }
Exemplo n.º 21
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Build Electron Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                //This version will be shared between the dotnet publish and electron-builder commands
                string version = null;
                if (parser.Arguments.ContainsKey(_paramVersion))
                {
                    version = parser.Arguments[_paramVersion][0];
                }

                if (!parser.Arguments.ContainsKey(_paramTarget) || parser.Arguments[_paramTarget].Length == 0)
                {
                    Console.WriteLine($"Error: missing '{_paramTarget}' argument.");
                    Console.WriteLine(COMMAND_ARGUMENTS);
                    return false;
                }

                var desiredPlatform = parser.Arguments[_paramTarget][0];
                string specifiedFromCustom = string.Empty;
                if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
                {
                    specifiedFromCustom = parser.Arguments[_paramTarget][1];
                }

                string configuration = "Release";
                if (parser.Arguments.ContainsKey(_paramDotNetConfig))
                {
                    configuration = parser.Arguments[_paramDotNetConfig][0];
                }

                var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}...");

                string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform);

                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }
                else
                {
                    Directory.Delete(tempPath, true);
                    Directory.CreateDirectory(tempPath);
                }


                Console.WriteLine("Executing dotnet publish in this directory: " + tempPath);

                string tempBinPath = Path.Combine(tempPath, "bin");

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration...");

                var dotNetPublishFlags = GetDotNetPublishFlags(parser);

                var command =
                    $"dotnet publish -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))} --self-contained";

                // output the command
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(command);
                Console.ResetColor();

                var resultCode = ProcessHelper.CmdExecute(command, Directory.GetCurrentDirectory());

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);
                var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                if (parser.Arguments.ContainsKey(_paramPackageJson))
                {
                    Console.WriteLine("Copying custom package.json.");

                    File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true);
                }

                var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
                {
                    Console.WriteLine("Start npm install...");
                }
                ProcessHelper.CmdExecute("npm install --production", tempPath);

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
                }

                Console.WriteLine("Build Electron Desktop Application...");

                // Specifying an absolute path supercedes a relative path
                string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop");
                if (parser.Arguments.ContainsKey(_paramAbsoluteOutput))
                {
                    buildPath = parser.Arguments[_paramAbsoluteOutput][0];
                }
                else if (parser.Arguments.ContainsKey(_paramOutputDirectory))
                {
                    buildPath = Path.Combine(Directory.GetCurrentDirectory(), parser.Arguments[_paramOutputDirectory][0]);
                }

                Console.WriteLine("Executing electron magic in this directory: " + buildPath);

                string electronArch = "x64";
                if (parser.Arguments.ContainsKey(_paramElectronArch))
                {
                    electronArch = parser.Arguments[_paramElectronArch][0];
                }

                string electronParams = "";
                if (parser.Arguments.ContainsKey(_paramElectronParams))
                {
                    electronParams = parser.Arguments[_paramElectronParams][0];
                }

                // ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :)
                Console.WriteLine("Create electron-builder configuration file...");

                string manifestFileName = "electron.manifest.json";

                if (parser.Arguments.ContainsKey(_manifest))
                {
                    manifestFileName = parser.Arguments[_manifest].First();
                }

                ProcessHelper.CmdExecute(
                    string.IsNullOrWhiteSpace(version)
                        ? $"node build-helper.js {manifestFileName}"
                        : $"node build-helper.js {manifestFileName} {version}", tempPath);

                Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
                ProcessHelper.CmdExecute($"npx electron-builder --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=13.1.5 {electronParams}", tempPath);

                Console.WriteLine("... done");

                return true;
            }));
        }
Exemplo n.º 22
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Start Electron Desktop Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                string aspCoreProjectPath = "";

                if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
                {
                    string projectPath = parser.Arguments[_aspCoreProjectPath].First();
                    if (Directory.Exists(projectPath))
                    {
                        aspCoreProjectPath = projectPath;
                    }
                }
                else
                {
                    aspCoreProjectPath = Directory.GetCurrentDirectory();
                }

                string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");
                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }

                var platformInfo = GetTargetPlatformInformation.Do(string.Empty, string.Empty);

                string tempBinPath = Path.Combine(tempPath, "bin");
                var resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} --output \"{tempBinPath}\"", aspCoreProjectPath);

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);

                var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                Console.WriteLine("node_modules missing in: " + nodeModulesDirPath);

                Console.WriteLine("Start npm install...");
                ProcessHelper.CmdExecute("npm install", tempPath);

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for typescript & hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p ../../ElectronHostHook", tempPath);
                }

                string arguments = "";

                if (parser.Arguments.ContainsKey(_arguments))
                {
                    arguments = string.Join(' ', parser.Arguments[_arguments]);
                }

                if (parser.Arguments.ContainsKey(_manifest))
                {
                    arguments += " --manifest=" + parser.Arguments[_manifest].First();
                }

                string path = Path.Combine(tempPath, "node_modules", ".bin");
                bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                if (isWindows)
                {
                    Console.WriteLine("Invoke electron.cmd - in dir: " + path);
                    ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
                }
                else
                {
                    Console.WriteLine("Invoke electron - in dir: " + path);
                    ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
                }

                return true;
            }));
        }
Exemplo n.º 23
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Build Electron Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                var desiredPlatform = parser.Arguments[_paramTarget][0];
                string specifiedFromCustom = string.Empty;
                if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
                {
                    specifiedFromCustom = parser.Arguments[_paramTarget][1];
                }

                string configuration = "Release";
                if (parser.Arguments.ContainsKey(_paramDotNetConfig))
                {
                    configuration = parser.Arguments[_paramDotNetConfig][0];
                }

                var platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid}...");

                string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "obj", "desktop", desiredPlatform);

                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }

                Console.WriteLine("Executing dotnet publish in this directory: " + tempPath);

                string tempBinPath = Path.Combine(tempPath, "bin");

                Console.WriteLine($"Build ASP.NET Core App for {platformInfo.NetCorePublishRid} under {configuration}-Configuration...");

                var resultCode = ProcessHelper.CmdExecute($"dotnet publish -r {platformInfo.NetCorePublishRid} -c {configuration} --output \"{tempBinPath}\"", Directory.GetCurrentDirectory());

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);
                var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                if (parser.Arguments.ContainsKey(_paramPackageJson))
                {
                    Console.WriteLine("Copying custom package.json.");

                    File.Copy(parser.Arguments[_paramPackageJson][0], Path.Combine(tempPath, "package.json"), true);
                }

                var checkForNodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                if (Directory.Exists(checkForNodeModulesDirPath) == false || parser.Contains(_paramForceNodeInstall) || parser.Contains(_paramPackageJson))
                {
                    Console.WriteLine("Start npm install...");
                }
                ProcessHelper.CmdExecute("npm install --production", tempPath);

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p . --sourceMap false", hosthookDir);
                }

                Console.WriteLine("Build Electron Desktop Application...");

                // Specifying an absolute path supercedes a relative path
                string buildPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "desktop");
                if (parser.Arguments.ContainsKey(_paramAbsoluteOutput))
                {
                    buildPath = parser.Arguments[_paramAbsoluteOutput][0];
                }
                else if (parser.Arguments.ContainsKey(_paramOutputDirectory))
                {
                    buildPath = Path.Combine(Directory.GetCurrentDirectory(), parser.Arguments[_paramOutputDirectory][0]);
                }

                Console.WriteLine("Executing electron magic in this directory: " + buildPath);

                string electronArch = "x64";
                if (parser.Arguments.ContainsKey(_paramElectronArch))
                {
                    electronArch = parser.Arguments[_paramElectronArch][0];
                }

                string electronParams = "";
                if (parser.Arguments.ContainsKey(_paramElectronParams))
                {
                    electronParams = parser.Arguments[_paramElectronParams][0];
                }

                // ToDo: Make the same thing easer with native c# - we can save a tmp file in production code :)
                Console.WriteLine("Create electron-builder configuration file...");
                ProcessHelper.CmdExecute($"node build-helper.js", tempPath);

                Console.WriteLine($"Package Electron App for Platform {platformInfo.ElectronPackerPlatform}...");
                ProcessHelper.CmdExecute($"npx electron-builder . --config=./bin/electron-builder.json --{platformInfo.ElectronPackerPlatform} --{electronArch} -c.electronVersion=5.0.8 {electronParams}", tempPath);

                Console.WriteLine("... done");

                return true;
            }));
        }
Exemplo n.º 24
0
        public Task <bool> ExecuteAsync()
        {
            return(Task.Run(() =>
            {
                Console.WriteLine("Start Electron Desktop Application...");

                SimpleCommandLineParser parser = new SimpleCommandLineParser();
                parser.Parse(_args);

                string aspCoreProjectPath = "";

                if (parser.Arguments.ContainsKey(_aspCoreProjectPath))
                {
                    string projectPath = parser.Arguments[_aspCoreProjectPath].First();
                    if (Directory.Exists(projectPath))
                    {
                        aspCoreProjectPath = projectPath;
                    }
                }
                else
                {
                    aspCoreProjectPath = Directory.GetCurrentDirectory();
                }

                string tempPath = Path.Combine(aspCoreProjectPath, "obj", "Host");
                if (Directory.Exists(tempPath) == false)
                {
                    Directory.CreateDirectory(tempPath);
                }

                string tempBinPath = Path.GetFullPath(Path.Combine(tempPath, "bin"));

                var dotNetPublishFlags = BuildCommand.GetDotNetPublishFlags(parser, "false", "false");

                var resultCode = 0;


                // If target is specified as a command line argument, use it.
                // Format is the same as the build command.
                // If target is not specified, autodetect it.
                var platformInfo = GetTargetPlatformInformation.Do(string.Empty, string.Empty);
                if (parser.Arguments.ContainsKey(_paramTarget))
                {
                    var desiredPlatform = parser.Arguments[_paramTarget][0];
                    string specifiedFromCustom = string.Empty;
                    if (desiredPlatform == "custom" && parser.Arguments[_paramTarget].Length > 1)
                    {
                        specifiedFromCustom = parser.Arguments[_paramTarget][1];
                    }
                    platformInfo = GetTargetPlatformInformation.Do(desiredPlatform, specifiedFromCustom);
                }

                string configuration = "Debug";
                if (parser.Arguments.ContainsKey(_paramDotNetConfig))
                {
                    configuration = parser.Arguments[_paramDotNetConfig][0];
                }

                var project = string.Empty;
                if (parser.Arguments.ContainsKey(_paramDotNetProject))
                {
                    project = parser.Arguments[_paramDotNetProject][0];
                }

                if (!parser.Arguments.ContainsKey("watch"))
                {
                    resultCode = ProcessHelper.CmdExecute($"dotnet publish {project} -r {platformInfo.NetCorePublishRid} -c \"{configuration}\" --output \"{tempBinPath}\" {string.Join(' ', dotNetPublishFlags.Select(kvp => $"{kvp.Key}={kvp.Value}"))} /p:DisabledWarnings=true", aspCoreProjectPath);
                }

                if (resultCode != 0)
                {
                    Console.WriteLine("Error occurred during dotnet publish: " + resultCode);
                    return false;
                }

                DeployEmbeddedElectronFiles.Do(tempPath);

                var nodeModulesDirPath = Path.Combine(tempPath, "node_modules");

                bool runNpmInstall = false;

                Console.WriteLine("node_modules in: " + nodeModulesDirPath);

                if (!Directory.Exists(nodeModulesDirPath))
                {
                    runNpmInstall = true;
                }

                var packagesJson = Path.Combine(tempPath, "package.json");
                var packagesPrevious = Path.Combine(tempPath, "package.json.previous");

                if (!runNpmInstall)
                {
                    if (File.Exists(packagesPrevious))
                    {
                        if (File.ReadAllText(packagesPrevious) != File.ReadAllText(packagesJson))
                        {
                            runNpmInstall = true;
                        }
                    }
                    else
                    {
                        runNpmInstall = true;
                    }
                }

                if (runNpmInstall)
                {
                    Console.WriteLine("Start npm install...");
                    ProcessHelper.CmdExecute("npm install", tempPath);
                    File.Copy(packagesJson, packagesPrevious, true);
                }

                Console.WriteLine("ElectronHostHook handling started...");

                string electronhosthookDir = Path.Combine(Directory.GetCurrentDirectory(), "ElectronHostHook");

                if (Directory.Exists(electronhosthookDir))
                {
                    string hosthookDir = Path.Combine(tempPath, "ElectronHostHook");
                    DirectoryCopy.Do(electronhosthookDir, hosthookDir, true, new List <string>()
                    {
                        "node_modules"
                    });

                    Console.WriteLine("Start npm install for typescript & hosthooks...");
                    ProcessHelper.CmdExecute("npm install", hosthookDir);

                    // ToDo: Not sure if this runs under linux/macos
                    ProcessHelper.CmdExecute(@"npx tsc -p ../../ElectronHostHook", tempPath);
                }

                string arguments = "";

                if (parser.Arguments.ContainsKey(_arguments))
                {
                    arguments = string.Join(' ', parser.Arguments[_arguments]);
                }

                if (parser.Arguments.ContainsKey(_manifest))
                {
                    arguments += " --manifest=" + parser.Arguments[_manifest].First();
                }

                if (parser.Arguments.ContainsKey(_clearCache))
                {
                    arguments += " --clear-cache=true";
                }

                if (parser.Arguments.ContainsKey("watch"))
                {
                    arguments += " --watch=true";
                }

                string path = Path.Combine(tempPath, "node_modules", ".bin");
                bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                if (isWindows)
                {
                    Console.WriteLine("Invoke electron.cmd - in dir: " + path);
                    Console.WriteLine("\n\n---------------------------------------------------\n\n\n");
                    ProcessHelper.CmdExecute(@"electron.cmd ""..\..\main.js"" " + arguments, path);
                }
                else
                {
                    Console.WriteLine("Invoke electron - in dir: " + path);
                    Console.WriteLine("\n\n---------------------------------------------------\n\n\n");
                    ProcessHelper.CmdExecute(@"./electron ""../../main.js"" " + arguments, path);
                }

                return true;
            }));
        }
 private void CopyExistingBaseline()
 {
     Console.WriteLine("Copying baseline directory to comparison directory.");
     DirectoryCopy.CopyDirectory(_baselineRoot, _comparisonRoot, true);
 }
Exemplo n.º 26
0
        public async Task SingleProjectRunTest()
        {
            var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "single-project", "test-project"));

            using var tempDirectory = TempDirectory.Create();
            DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath);

            var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "test-project.csproj"));

            using var host = new TyeHost(ConfigFactory.FromFile(projectFile).ToHostingApplication(), Array.Empty <string>())
                  {
                      Sink = sink,
                  };

            await host.StartAsync();

            try
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = (a, b, c, d) => true,
                    AllowAutoRedirect = false
                };

                var client = new HttpClient(new RetryHandler(handler));

                // Make sure dashboard and applications are up.
                // Dashboard should be hosted in same process.
                var dashboardUri      = new Uri(host.DashboardWebApplication !.Addresses.First());
                var dashboardResponse = await client.GetStringAsync(dashboardUri);

                // Only one service for single application.
                var service = host.Application.Services.First().Value;
                var binding = service.Description.Bindings.First();

                var protocol = binding.Protocol?.Length != 0 ? binding.Protocol : "http";
                var hostName = binding.Host != null && binding.Host.Length != 0 ? binding.Host : "localhost";

                var uriString = $"{protocol}://{hostName}:{binding.Port}";

                // Confirm that the uri is in the dashboard response.
                Assert.Contains(uriString, dashboardResponse);

                var uriBackendProcess = new Uri(uriString);

                // This isn't reliable right now because micronetes only guarantees the process starts, not that
                // that kestrel started.
                try
                {
                    var appResponse = await client.GetAsync(uriBackendProcess);

                    Assert.Equal(HttpStatusCode.OK, appResponse.StatusCode);
                }
                finally
                {
                    // If we failed, there's a good chance the service isn't running. Let's get the logs either way and put
                    // them in the output.
                    var request  = new HttpRequestMessage(HttpMethod.Get, new Uri(dashboardUri, $"/api/v1/logs/{service.Description.Name}"));
                    var response = await client.SendAsync(request);

                    var text = await response.Content.ReadAsStringAsync();

                    output.WriteLine($"Logs for service: {service.Description.Name}");
                    output.WriteLine(text);
                }
            }
            finally
            {
                await host.StopAsync();
            }
        }
Exemplo n.º 27
0
        public async Task <ExitCode> ExecuteAsync(
            ILogger logger,
            IReadOnlyCollection <IVariable> buildVariables,
            CancellationToken cancellationToken)
        {
            _kuduEnabled = buildVariables.HasKey(WellKnownVariables.ExternalTools_Kudu_Enabled) &&
                           bool.Parse(buildVariables.Require(WellKnownVariables.ExternalTools_Kudu_Enabled).Value);
            if (!_kuduEnabled)
            {
                return(ExitCode.Success);
            }

            _vcsRoot   = buildVariables.Require(WellKnownVariables.SourceRoot).ThrowIfEmptyValue().Value;
            _artifacts = buildVariables.Require(WellKnownVariables.Artifacts).ThrowIfEmptyValue().Value;
            buildVariables.Require(WellKnownVariables.ExternalTools_Kudu_Platform).ThrowIfEmptyValue();
            _deployBranch = new BranchName(buildVariables
                                           .Require(WellKnownVariables.ExternalTools_Kudu_DeploymentBranchName)
                                           .Value);
            _deploymentTargetDirectory =
                buildVariables.Require(WellKnownVariables.ExternalTools_Kudu_DeploymentTarget).Value;

            _kuduConfigurationFallback = buildVariables.HasKey(WellKnownVariables.KuduConfigurationFallback)
                ? buildVariables.Require(WellKnownVariables.KuduConfigurationFallback).Value
                : string.Empty;

            _clearTarget                 = buildVariables.GetBooleanByKey(WellKnownVariables.KuduClearFilesAndDirectories, false);
            _useAppOfflineFile           = buildVariables.GetBooleanByKey(WellKnownVariables.KuduUseAppOfflineHtmFile, false);
            _excludeAppData              = buildVariables.GetBooleanByKey(WellKnownVariables.KuduExcludeDeleteAppData, true);
            _deleteExistingAppOfflineHtm =
                buildVariables.GetBooleanByKey(WellKnownVariables.KuduDeleteExistingAppOfflineHtmFile, true);
            _ignoreDeleteFiles =
                buildVariables.GetVariableValueOrDefault(WellKnownVariables.KuduIgnoreDeleteFiles, string.Empty);
            _ignoreDeleteDirectories =
                buildVariables.GetVariableValueOrDefault(WellKnownVariables.KuduIgnoreDeleteDirectories, string.Empty);

            string branchNameOverride =
                buildVariables.GetVariableValueOrDefault(
                    WellKnownVariables.ExternalTools_Kudu_DeploymentBranchNameOverride,
                    string.Empty);

            if (!string.IsNullOrWhiteSpace(branchNameOverride))
            {
                logger.Write(
                    $"Using branch name override '{branchNameOverride}' instead of branch name '{_deployBranch}'");
                _deployBranch = new BranchName(branchNameOverride);
            }

            var websitesDirectory = new DirectoryInfo(Path.Combine(_artifacts, "Websites"));

            if (!websitesDirectory.Exists)
            {
                logger.Write("No websites found. Ignoring Kudu deployment.");
                return(ExitCode.Success);
            }

            DirectoryInfo[] builtWebsites = websitesDirectory.GetDirectories();

            if (!builtWebsites.Any())
            {
                logger.Write("No websites found. Ignoring Kudu deployment.");
                return(ExitCode.Success);
            }

            DirectoryInfo websiteToDeploy;

            if (builtWebsites.Length == 1)
            {
                websiteToDeploy = builtWebsites.Single();
            }
            else
            {
                string siteToDeploy =
                    buildVariables.GetVariableValueOrDefault(WellKnownVariables.KuduSiteToDeploy, string.Empty);
                if (!string.IsNullOrWhiteSpace(siteToDeploy))
                {
                    DirectoryInfo foundDir = builtWebsites.SingleOrDefault(
                        dir => dir.Name.Equals(siteToDeploy, StringComparison.InvariantCultureIgnoreCase));

                    if (foundDir == null)
                    {
                        logger.WriteError(
                            $"Found {builtWebsites.Length} websites. Kudu deployment is specified for site {siteToDeploy} but it was not found");
                        return(ExitCode.Failure);
                    }

                    websiteToDeploy = foundDir;
                }
                else
                {
                    logger.WriteError(
                        $"Found {builtWebsites.Length} websites. Kudu deployment is only supported with a single website. \r\nBuilt websites: {string.Join(Environment.NewLine, builtWebsites.Select(dir => dir.Name))}. You can use variable '{WellKnownVariables.KuduSiteToDeploy}' to specify a single website to be built");
                    return(ExitCode.Failure);
                }
            }

            if (!websiteToDeploy.GetDirectories().Any())
            {
                logger.WriteError($"Could not find any platform for website {websiteToDeploy.Name}");
                return(ExitCode.Failure);
            }

            if (websiteToDeploy.GetDirectories().Length > 1)
            {
                logger.WriteError($"Could not find exactly one platform for website {websiteToDeploy.Name}");
                return(ExitCode.Failure);
            }

            DirectoryInfo platform = GetPlatform(websiteToDeploy);

            if (!platform.GetDirectories().Any())
            {
                logger.WriteError($"Could not find any configuration for website {websiteToDeploy.Name}");
                return(ExitCode.Failure);
            }

            DirectoryInfo configuration = GetConfigurationDirectory(platform, logger);

            if (configuration == null)
            {
                logger.WriteError("No configuration for Kudu");
                return(ExitCode.Failure);
            }

            string appOfflinePath = Path.Combine(_deploymentTargetDirectory, "app_offline.htm");

            logger.Write(
                $"___________________ Kudu deploy ___________________ \r\nDeploying website {websiteToDeploy.Name}, platform {platform.Name}, configuration {configuration.Name}");
            try
            {
                if (_useAppOfflineFile)
                {
                    logger.WriteVerbose($"Flag '{WellKnownVariables.KuduUseAppOfflineHtmFile}' is set");
                    try
                    {
                        using (var fs = new FileStream(appOfflinePath, FileMode.Create, FileAccess.Write))
                        {
                            using (var streamWriter = new StreamWriter(fs, Encoding.UTF8))
                            {
                                streamWriter.WriteLine(
                                    "File created by Arbor.X Kudu at {0} (UTC)",
                                    DateTime.UtcNow.ToString("O"));
                            }
                        }
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        logger.WriteWarning(
                            $"Could not create app_offline.htm file in '{_deploymentTargetDirectory}', {ex}");
                    }
                    catch (IOException ex)
                    {
                        logger.WriteWarning(
                            $"Could not create app_offline.htm file in '{_deploymentTargetDirectory}', {ex}");
                    }
                }
                else
                {
                    logger.WriteVerbose($"Flag '{WellKnownVariables.KuduUseAppOfflineHtmFile}' is not set");
                }

                if (_clearTarget)
                {
                    logger.WriteVerbose($"Flag '{WellKnownVariables.KuduClearFilesAndDirectories}' is set");
                    logger.Write($"Removing files and directories from target '{_deploymentTargetDirectory}'");
                    try
                    {
                        var directoryFilters = new List <string>();

                        if (_excludeAppData)
                        {
                            directoryFilters.Add("App_Data");
                        }

                        string[] customFileExcludes      = GetExcludes(_ignoreDeleteFiles).ToArray();
                        string[] customDirectoryExcludes = GetExcludes(_ignoreDeleteDirectories).ToArray();

                        var fileFilters = new List <string>();

                        if (_useAppOfflineFile || !_deleteExistingAppOfflineHtm)
                        {
                            fileFilters.Add("app_offline.htm");
                        }

                        if (customDirectoryExcludes.Any())
                        {
                            logger.WriteVerbose("Adding directory ignore patterns " + string.Join(
                                                    "|",
                                                    $"'{customDirectoryExcludes.Select(item => (object)item)}'"));
                        }

                        if (customFileExcludes.Any())
                        {
                            logger.WriteVerbose("Adding file ignore patterns " + string.Join(
                                                    "|",
                                                    $"'{customFileExcludes.Select(item => (object)item)}'"));
                        }

                        directoryFilters.AddRange(customDirectoryExcludes);
                        fileFilters.AddRange(customFileExcludes);

                        var deleter = new DirectoryDelete(directoryFilters, fileFilters, logger);

                        deleter.Delete(_deploymentTargetDirectory, false, true);
                    }
                    catch (IOException ex)
                    {
                        logger.WriteWarning(
                            $"Could not clear all files and directories from target '{_deploymentTargetDirectory}', {ex}");
                    }
                }
                else
                {
                    logger.WriteVerbose(
                        $"Flag '{WellKnownVariables.KuduClearFilesAndDirectories}' is not set, skipping deleting files and directories from target '{_deploymentTargetDirectory}'");
                }

                logger.Write(
                    $"Copying files and directories from '{configuration.FullName}' to '{_deploymentTargetDirectory}'");

                try
                {
                    ExitCode exitCode = await DirectoryCopy.CopyAsync(
                        configuration.FullName,
                        _deploymentTargetDirectory,
                        logger,
                        rootDir : _vcsRoot,
                        pathLookupSpecificationOption : new PathLookupSpecification());

                    if (!exitCode.IsSuccess)
                    {
                        return(exitCode);
                    }
                }
                catch (Exception ex)
                {
                    logger.WriteError($"Kudu deploy could not copy files {ex}");
                    return(ExitCode.Failure);
                }
            }
            finally
            {
                if (_useAppOfflineFile || _deleteExistingAppOfflineHtm)
                {
                    if (File.Exists(appOfflinePath))
                    {
                        try
                        {
                            File.Delete(appOfflinePath);
                        }
                        catch (IOException ex)
                        {
                            logger.WriteWarning(
                                $"Could not delete app_offline.htm file in '{_deploymentTargetDirectory}', {ex}");
                        }
                    }
                }
            }

            return(ExitCode.Success);
        }