public IDictionary <string, string> GetToolsToBeSetInPath( RepositoryContext context, PlatformDetectorResult detectorResult) { var pythonPlatformDetectorResult = detectorResult as PythonPlatformDetectorResult; if (pythonPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(PythonPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } // Since conda is already in the path we do not need to set it explicitly in the path if (pythonPlatformDetectorResult.HasCondaEnvironmentYmlFile || pythonPlatformDetectorResult.HasJupyterNotebookFiles) { return(null); } var tools = new Dictionary <string, string>(); tools[PythonConstants.PlatformName] = pythonPlatformDetectorResult.PlatformVersion; return(tools); }
/// <inheritdoc/> public IDictionary <string, string> GetToolsToBeSetInPath( RepositoryContext context, PlatformDetectorResult detectorResult) { var javaPlatformDetectorResult = detectorResult as JavaPlatformDetectorResult; if (javaPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(JavaPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var tools = new Dictionary <string, string>(); tools[JavaConstants.PlatformName] = javaPlatformDetectorResult.PlatformVersion; if (javaPlatformDetectorResult.UsesMaven && !javaPlatformDetectorResult.UsesMavenWrapperTool) { tools[JavaConstants.MavenName] = javaPlatformDetectorResult.MavenVersion; } return(tools); }
public string GetInstallerScriptSnippet(BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var rubyPlatformDetectorResult = detectorResult as RubyPlatformDetectorResult; if (rubyPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(RubyPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (_commonOptions.EnableDynamicInstall) { _logger.LogDebug("Dynamic install is enabled."); var scriptBuilder = new StringBuilder(); InstallRuby(rubyPlatformDetectorResult.PlatformVersion, scriptBuilder); if (scriptBuilder.Length == 0) { return(null); } return(scriptBuilder.ToString()); } else { _logger.LogDebug("Dynamic install not enabled."); return(null); } }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var dotNetCorePlatformDetectorResult = detectorResult as DotNetCorePlatformDetectorResult; if (dotNetCorePlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(DotNetCorePlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var manifestFileProperties = new Dictionary <string, string>(); manifestFileProperties[ManifestFilePropertyKeys.OperationId] = context.OperationId; manifestFileProperties[ManifestFilePropertyKeys.DotNetCoreRuntimeVersion] = dotNetCorePlatformDetectorResult.PlatformVersion; manifestFileProperties[ManifestFilePropertyKeys.DotNetCoreSdkVersion] = dotNetCorePlatformDetectorResult.SdkVersion; // optional field string outputType = dotNetCorePlatformDetectorResult.OutputType; if (!string.IsNullOrEmpty(outputType)) { manifestFileProperties[ManifestFilePropertyKeys.OutputType] = outputType; } var projectFile = dotNetCorePlatformDetectorResult.ProjectFile; if (string.IsNullOrEmpty(projectFile)) { return(null); } var templateProperties = new DotNetCoreBashBuildSnippetProperties { ProjectFile = projectFile, Configuration = GetBuildConfiguration(), }; var script = TemplateHelper.Render( TemplateHelper.TemplateResource.DotNetCoreSnippet, templateProperties, _logger); SetStartupFileNameInfoInManifestFile(context, projectFile, manifestFileProperties); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = manifestFileProperties, // Setting this to false to avoid copying files like '.cs' to the destination CopySourceDirectoryContentToDestinationDirectory = false, }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { var phpPlatformDetectorResult = detectorResult as PhpPlatformDetectorResult; if (phpPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(PhpPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var buildProperties = new Dictionary <string, string>(); // Write the platform name and version to the manifest file buildProperties[ManifestFilePropertyKeys.PhpVersion] = phpPlatformDetectorResult.PlatformVersion; this.logger.LogDebug("Selected PHP version: {phpVer}", phpPlatformDetectorResult.PlatformVersion); bool composerFileExists = false; if (ctx.SourceRepo.FileExists(PhpConstants.ComposerFileName)) { composerFileExists = true; try { dynamic composerFile = ctx.SourceRepo.ReadJsonObjectFromFile(PhpConstants.ComposerFileName); if (composerFile?.require != null) { Newtonsoft.Json.Linq.JObject deps = composerFile?.require; var depSpecs = deps.ToObject <IDictionary <string, string> >(); this.logger.LogDependencies( this.Name, phpPlatformDetectorResult.PlatformVersion, depSpecs.Select(kv => kv.Key + kv.Value)); } } catch (Exception exc) { // Leave malformed composer.json files for Composer to handle. // This prevents Oryx from erroring out when Composer itself might be able to tolerate the file. this.logger.LogWarning(exc, $"Exception caught while trying to deserialize {PhpConstants.ComposerFileName.Hash()}"); } } var props = new PhpBashBuildSnippetProperties { ComposerFileExists = composerFileExists }; string snippet = TemplateHelper.Render(TemplateHelper.TemplateResource.PhpBuildSnippet, props, this.logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = snippet, BuildProperties = buildProperties }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { var rubyPlatformDetectorResult = detectorResult as RubyPlatformDetectorResult; if (rubyPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(RubyPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (!rubyPlatformDetectorResult.GemfileExists && !rubyPlatformDetectorResult.ConfigYmlFileExists) { throw new InvalidUsageException($"No Gemfile found at the root of the repo. Please provide a Gemfile. " + $"For Jekyll apps, make sure it contains a '{RubyConstants.ConfigYmlFileName}' file and set it as a static web app"); } var buildProperties = new Dictionary <string, string>(); if (RubyConstants.ConfigYmlFileName != null) { buildProperties[ManifestFilePropertyKeys.Frameworks] = "jekyll"; this.logger.LogInformation("Detected the following frameworks: jekyll"); Console.WriteLine("Detected the following frameworks: jekyll"); } // Write the platform name and version to the manifest file buildProperties[ManifestFilePropertyKeys.RubyVersion] = rubyPlatformDetectorResult.PlatformVersion; this.logger.LogDebug("Selected Ruby version: {rubyVer}", rubyPlatformDetectorResult.PlatformVersion); var scriptProps = new RubyBashBuildSnippetProperties { UseBundlerToInstallDependencies = true, BundlerVersion = rubyPlatformDetectorResult.BundlerVersion, GemfileExists = rubyPlatformDetectorResult.GemfileExists, ConfigYmlFileExists = rubyPlatformDetectorResult.ConfigYmlFileExists, CustomBuildCommand = this.rubyScriptGeneratorOptions.CustomBuildCommand, }; string script = TemplateHelper.Render( TemplateHelper.TemplateResource.RubyBuildSnippet, scriptProps, this.logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = buildProperties, }); }
/// <inheritdoc/> public void ResolveVersions(RepositoryContext context, PlatformDetectorResult detectorResult) { var rubyPlatformDetectorResult = detectorResult as RubyPlatformDetectorResult; if (rubyPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(RubyPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } ResolveVersionsUsingHierarchicalRules(rubyPlatformDetectorResult); }
public IDictionary <string, string> GetToolsToBeSetInPath(RepositoryContext context, PlatformDetectorResult detectorResult) { var golangPlatformDetectorResult = detectorResult as GolangPlatformDetectorResult; if (golangPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(GolangPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var tools = new Dictionary <string, string>(); tools[GolangConstants.PlatformName] = golangPlatformDetectorResult.PlatformVersion; return(tools); }
/// <inheritdoc/> public string GetInstallerScriptSnippet( BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var dotNetCorePlatformDetectorResult = detectorResult as DotNetCorePlatformDetectorResult; if (dotNetCorePlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(DotNetCorePlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } string installationScriptSnippet = null; if (this.commonOptions.EnableDynamicInstall) { this.logger.LogDebug("Dynamic install is enabled."); if (this.platformInstaller.IsVersionAlreadyInstalled(dotNetCorePlatformDetectorResult.SdkVersion)) { this.logger.LogDebug( "DotNetCore SDK version {globalJsonSdkVersion} is already installed. " + "So skipping installing it again.", dotNetCorePlatformDetectorResult.SdkVersion); } else { this.logger.LogDebug( "DotNetCore SDK version {globalJsonSdkVersion} is not installed. " + "So generating an installation script snippet for it.", dotNetCorePlatformDetectorResult.SdkVersion); installationScriptSnippet = this.platformInstaller.GetInstallerScriptSnippet( dotNetCorePlatformDetectorResult.SdkVersion); } } else { this.logger.LogDebug("Dynamic install is not enabled."); } return(installationScriptSnippet); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { var rubyPlatformDetectorResult = detectorResult as RubyPlatformDetectorResult; if (rubyPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(RubyPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (!rubyPlatformDetectorResult.GemfileExists) { throw new InvalidUsageException($"No Gemfile found at the root of the repo. Please provide a Gemfile."); } var buildProperties = new Dictionary <string, string>(); // Write the platform name and version to the manifest file buildProperties[ManifestFilePropertyKeys.RubyVersion] = rubyPlatformDetectorResult.PlatformVersion; _logger.LogDebug("Selected Ruby version: {rubyVer}", rubyPlatformDetectorResult.PlatformVersion); var scriptProps = new RubyBashBuildSnippetProperties { UseBundlerToInstallDependencies = true, BundlerVersion = rubyPlatformDetectorResult.BundlerVersion, }; string script = TemplateHelper.Render( TemplateHelper.TemplateResource.RubyBuildSnippet, scriptProps, _logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = buildProperties, }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { // confirm go detector not null var goPlatformDetectorResult = detectorResult as GolangPlatformDetectorResult; if (goPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(GolangPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (!goPlatformDetectorResult.GoModExists) { throw new InvalidUsageException("No go.mod found at the root of the repo. Please provide a go.mod file containing the version."); } // build properties & script snippets var buildProperties = new Dictionary <string, string>(); // Write platform name and version to the manifest file buildProperties[ManifestFilePropertyKeys.GolangVersion] = goPlatformDetectorResult.PlatformVersion; this.logger.LogDebug($"Selected Go version: {goPlatformDetectorResult.PlatformVersion}"); var scriptProps = new GolangBashBuildSnippetProperties( goPlatformDetectorResult.GoModExists, goPlatformDetectorResult.PlatformVersion); string script = TemplateHelper.Render( TemplateHelper.TemplateResource.GolangSnippet, scriptProps, this.logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = buildProperties, }); }
/// <inheritdoc/> public string GetInstallerScriptSnippet( BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var javaPlatformDetectorResult = detectorResult as JavaPlatformDetectorResult; if (javaPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(JavaPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (_commonOptions.EnableDynamicInstall) { _logger.LogDebug("Dynamic install is enabled."); var scriptBuilder = new StringBuilder(); InstallJavaSdk(javaPlatformDetectorResult.PlatformVersion, scriptBuilder); // We need not setup Maven if repo already uses a Maven wrapper script. if (!javaPlatformDetectorResult.UsesMavenWrapperTool) { InstallMaven(javaPlatformDetectorResult.MavenVersion, scriptBuilder); } if (scriptBuilder.Length == 0) { return(null); } return(scriptBuilder.ToString()); } else { _logger.LogDebug("Dynamic install not enabled."); return(null); } }
/// <inheritdoc/> public void ResolveVersions(RepositoryContext context, PlatformDetectorResult detectorResult) { var dotNetCorePlatformDetectorResult = detectorResult as DotNetCorePlatformDetectorResult; if (dotNetCorePlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(DotNetCorePlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } // Get runtime version var resolvedRuntimeVersion = this.GetRuntimeVersionUsingHierarchicalRules( dotNetCorePlatformDetectorResult.PlatformVersion); resolvedRuntimeVersion = this.GetMaxSatisfyingRuntimeVersionAndVerify(resolvedRuntimeVersion); dotNetCorePlatformDetectorResult.PlatformVersion = resolvedRuntimeVersion; var versionMap = this.versionProvider.GetSupportedVersions(); var sdkVersion = this.GetSdkVersion(context, dotNetCorePlatformDetectorResult.PlatformVersion, versionMap); dotNetCorePlatformDetectorResult.SdkVersion = sdkVersion; }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var pythonPlatformDetectorResult = detectorResult as PythonPlatformDetectorResult; if (pythonPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(PythonPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } if (IsCondaEnvironment(pythonPlatformDetectorResult)) { return(GetBuildScriptSnippetForConda(context, pythonPlatformDetectorResult)); } var manifestFileProperties = new Dictionary <string, string>(); // Write the platform name and version to the manifest file manifestFileProperties[ManifestFilePropertyKeys.PythonVersion] = pythonPlatformDetectorResult.PlatformVersion; var packageDir = GetPackageDirectory(context); var virtualEnvName = GetVirtualEnvironmentName(context); var isPythonPackageCommandEnabled = _commonOptions.ShouldPackage; var pythonPackageWheelType = GetPythonPackageWheelType(context); if (!isPythonPackageCommandEnabled && !string.IsNullOrWhiteSpace(pythonPackageWheelType)) { throw new InvalidUsageException($"Option '{PythonPackageWheelPropertyKey}' can't exist" + $"without package command being enabled. Please provide --package along with wheel type"); } if (isPythonPackageCommandEnabled && !string.IsNullOrWhiteSpace(pythonPackageWheelType)) { if (!string.Equals(pythonPackageWheelType.ToLower(), "universal")) { throw new InvalidUsageException($"Option '{PythonPackageWheelPropertyKey}' can only have 'universal' as value.'"); } manifestFileProperties[PythonManifestFilePropertyKeys.PackageWheel] = pythonPackageWheelType; } if (!string.IsNullOrWhiteSpace(packageDir) && !string.IsNullOrWhiteSpace(virtualEnvName)) { throw new InvalidUsageException($"Options '{TargetPackageDirectoryPropertyKey}' and " + $"'{VirtualEnvironmentNamePropertyKey}' are mutually exclusive. Please provide " + $"only the target package directory or virtual environment name."); } if (string.IsNullOrWhiteSpace(packageDir)) { // If the package directory was not provided, we default to virtual envs if (string.IsNullOrWhiteSpace(virtualEnvName)) { virtualEnvName = GetDefaultVirtualEnvName(pythonPlatformDetectorResult); } manifestFileProperties[PythonManifestFilePropertyKeys.VirtualEnvName] = virtualEnvName; } else { manifestFileProperties[PythonManifestFilePropertyKeys.PackageDir] = packageDir; } var virtualEnvModule = string.Empty; var virtualEnvParams = string.Empty; var pythonVersion = pythonPlatformDetectorResult.PlatformVersion; _logger.LogDebug("Selected Python version: {pyVer}", pythonVersion); if (!string.IsNullOrEmpty(pythonVersion) && !string.IsNullOrWhiteSpace(virtualEnvName)) { (virtualEnvModule, virtualEnvParams) = GetVirtualEnvModules(pythonVersion); _logger.LogDebug( "Using virtual environment {venv}, module {venvModule}", virtualEnvName, virtualEnvModule); } GetVirtualEnvPackOptions( context, virtualEnvName, out var compressVirtualEnvCommand, out var compressedVirtualEnvFileName); if (!string.IsNullOrWhiteSpace(compressedVirtualEnvFileName)) { manifestFileProperties[PythonManifestFilePropertyKeys.CompressedVirtualEnvFile] = compressedVirtualEnvFileName; } TryLogDependencies(pythonVersion, context.SourceRepo); var scriptProps = new PythonBashBuildSnippetProperties( virtualEnvironmentName: virtualEnvName, virtualEnvironmentModule: virtualEnvModule, virtualEnvironmentParameters: virtualEnvParams, packagesDirectory: packageDir, enableCollectStatic: _pythonScriptGeneratorOptions.EnableCollectStatic, compressVirtualEnvCommand: compressVirtualEnvCommand, compressedVirtualEnvFileName: compressedVirtualEnvFileName, runPythonPackageCommand: isPythonPackageCommandEnabled, pythonPackageWheelProperty: pythonPackageWheelType); string script = TemplateHelper.Render( TemplateHelper.TemplateResource.PythonSnippet, scriptProps, _logger); return(new BuildScriptSnippet() { BashBuildScriptSnippet = script, BuildProperties = manifestFileProperties, }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext context, PlatformDetectorResult detectorResult) { var dotNetCorePlatformDetectorResult = detectorResult as DotNetCorePlatformDetectorResult; if (dotNetCorePlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(DotNetCorePlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var versionMap = _versionProvider.GetSupportedVersions(); string globalJsonSdkVersion = null; if (_commonOptions.EnableDynamicInstall) { var availableSdks = versionMap.Values; globalJsonSdkVersion = _globalJsonSdkResolver.GetSatisfyingSdkVersion( context.SourceRepo, detectorResult.PlatformVersion, availableSdks); } var manifestFileProperties = new Dictionary <string, string>(); manifestFileProperties[ManifestFilePropertyKeys.OperationId] = context.OperationId; manifestFileProperties[ManifestFilePropertyKeys.DotNetCoreRuntimeVersion] = detectorResult.PlatformVersion; if (string.IsNullOrEmpty(globalJsonSdkVersion)) { manifestFileProperties[ManifestFilePropertyKeys.DotNetCoreSdkVersion] = versionMap[detectorResult.PlatformVersion]; } else { manifestFileProperties[ManifestFilePropertyKeys.DotNetCoreSdkVersion] = globalJsonSdkVersion; } var projectFile = dotNetCorePlatformDetectorResult.ProjectFile; if (string.IsNullOrEmpty(projectFile)) { return(null); } var templateProperties = new DotNetCoreBashBuildSnippetProperties { ProjectFile = projectFile, Configuration = GetBuildConfiguration(), }; var script = TemplateHelper.Render( TemplateHelper.TemplateResource.DotNetCoreSnippet, templateProperties, _logger); SetStartupFileNameInfoInManifestFile(context, projectFile, manifestFileProperties); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = manifestFileProperties, // Setting this to false to avoid copying files like '.cs' to the destination CopySourceDirectoryContentToDestinationDirectory = false, }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { var javaPlatformDetectorResult = detectorResult as JavaPlatformDetectorResult; if (javaPlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(JavaPlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var manifestFileProperties = new Dictionary <string, string>(); // Write the platform name and version to the manifest file manifestFileProperties[ManifestFilePropertyKeys.JavaVersion] = detectorResult.PlatformVersion; string command = string.Empty; if (javaPlatformDetectorResult.UsesMavenWrapperTool) { if (_commonOptions.ShouldPackage) { command = JavaConstants.CreatePackageCommandUsingMavenWrapper; } else { command = JavaConstants.CompileCommandUsingMavenWrapper; } } else if (javaPlatformDetectorResult.UsesMaven) { if (_commonOptions.ShouldPackage) { command = JavaConstants.CreatePackageCommandUsingMaven; } else { command = JavaConstants.CompileCommandUsingMaven; } // Maven spits out lot of information related to downloading of packages which is too verbose. // Since the --quiet option is too quiet, we are trying to use a new switch below to just mute the // messages related to transfer progress of these downloads. // https://maven.apache.org/docs/3.6.1/release-notes.html#user-visible-changes var currentMavenVersion = new SemVer.Version(javaPlatformDetectorResult.MavenVersion); if (currentMavenVersion.CompareTo(JavaConstants.MinMavenVersionWithNoTransferProgressSupport) >= 0) { command = $"{command} --no-transfer-progress"; } } var scriptProps = new JavaBashBuildSnippetProperties(); scriptProps.UsesMaven = javaPlatformDetectorResult.UsesMaven; scriptProps.UsesMavenWrapperTool = javaPlatformDetectorResult.UsesMavenWrapperTool; scriptProps.Command = command; string script = TemplateHelper.Render( TemplateHelper.TemplateResource.JavaBuildSnippet, scriptProps, _logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = manifestFileProperties, }); }
/// <inheritdoc/> public BuildScriptSnippet GenerateBashBuildScriptSnippet( BuildScriptGeneratorContext ctx, PlatformDetectorResult detectorResult) { var nodePlatformDetectorResult = detectorResult as NodePlatformDetectorResult; if (nodePlatformDetectorResult == null) { throw new ArgumentException( $"Expected '{nameof(detectorResult)}' argument to be of type " + $"'{typeof(NodePlatformDetectorResult)}' but got '{detectorResult.GetType()}'."); } var manifestFileProperties = new Dictionary <string, string>(); // Write the platform name and version to the manifest file manifestFileProperties[ManifestFilePropertyKeys.NodeVersion] = nodePlatformDetectorResult.PlatformVersion; var packageJson = GetPackageJsonObject(ctx.SourceRepo, _logger); string runBuildCommand = null; string runBuildAzureCommand = null; string runBuildLernaCommand = null; string runBuildLageCommand = null; string installLernaCommand = null; bool configureYarnCache = false; string yarnCacheFolderName = null; string packageManagerCmd = null; string packageInstallCommand = null; string packageInstallerVersionCommand = null; if (_nodeScriptGeneratorOptions.EnableNodeMonorepoBuild && nodePlatformDetectorResult.HasLernaJsonFile && nodePlatformDetectorResult.HasLageConfigJSFile) { _logger.LogError( "Could not build monorepo with multiple package management tools. Both 'lerna.json' and 'lage.config.js' files are found."); throw new InvalidUsageException("Multiple monorepo package management tools are found, please choose to use either Lerna or Lage."); } if (ctx.SourceRepo.FileExists(NodeConstants.YarnLockFileName)) { packageManagerCmd = NodeConstants.YarnCommand; configureYarnCache = false; packageInstallerVersionCommand = NodeConstants.YarnVersionCommand; // In Yarn 2+ and .yarnrc.yml file replaces .yarnrc in Yarn 2+. // Applying yarn 2 cache folder name and package install command. if (nodePlatformDetectorResult.HasYarnrcYmlFile) { yarnCacheFolderName = NodeConstants.Yarn2ConfigFolderName; packageInstallCommand = NodeConstants.Yarn2PackageInstallCommand; } else { yarnCacheFolderName = NodeConstants.Yarn1ConfigFolderName; packageInstallCommand = NodeConstants.YarnPackageInstallCommand; } } else { packageManagerCmd = NodeConstants.NpmCommand; packageInstallCommand = NodeConstants.NpmPackageInstallCommand; packageInstallerVersionCommand = NodeConstants.NpmVersionCommand; } if (_nodeScriptGeneratorOptions.EnableNodeMonorepoBuild) { // If a 'lerna.json' file exists, override the npm client that lerna chosen to build monorepo. if (nodePlatformDetectorResult.HasLernaJsonFile) { packageManagerCmd = nodePlatformDetectorResult.LernaNpmClient; runBuildLernaCommand = string.Format( NodeConstants.PkgMgrRunBuildCommandTemplate, NodeConstants.LernaCommand); if (!string.IsNullOrEmpty(nodePlatformDetectorResult.LernaNpmClient) && nodePlatformDetectorResult.LernaNpmClient.Equals( NodeConstants.YarnCommand, StringComparison.OrdinalIgnoreCase)) { packageInstallCommand = NodeConstants.YarnPackageInstallCommand; configureYarnCache = false; packageInstallerVersionCommand = NodeConstants.YarnVersionCommand; installLernaCommand = NodeConstants.InstallLernaCommandYarn; } else { packageInstallCommand = NodeConstants.NpmPackageInstallCommand; packageInstallerVersionCommand = NodeConstants.NpmVersionCommand; installLernaCommand = NodeConstants.InstallLernaCommandNpm; } } // If a 'lage.config.js' file exits, run build using lage specifc commands. if (nodePlatformDetectorResult.HasLageConfigJSFile) { runBuildLageCommand = ctx.SourceRepo.FileExists(NodeConstants.YarnLockFileName) ? NodeConstants.YarnRunLageBuildCommand : NodeConstants.NpmRunLageBuildCommand; } } _logger.LogInformation("Using {packageManager}", packageManagerCmd); var hasProdDependencies = false; if (packageJson?.dependencies != null) { hasProdDependencies = true; } var hasDevDependencies = false; if (packageJson?.devDependencies != null) { // If development time dependencies are present we want to avoid copying them to improve performance hasDevDependencies = true; } var productionOnlyPackageInstallCommand = string.Format( NodeConstants.ProductionOnlyPackageInstallCommandTemplate, packageInstallCommand); if (string.IsNullOrEmpty(_nodeScriptGeneratorOptions.CustomBuildCommand) && string.IsNullOrEmpty(_nodeScriptGeneratorOptions.CustomRunBuildCommand) && string.IsNullOrEmpty(runBuildLernaCommand) && string.IsNullOrEmpty(runBuildLageCommand)) { var scriptsNode = packageJson?.scripts; if (scriptsNode != null) { if (scriptsNode.build != null) { runBuildCommand = string.Format(NodeConstants.PkgMgrRunBuildCommandTemplate, packageManagerCmd); } if (scriptsNode["build:azure"] != null && !_commonOptions.ShouldPackage) { runBuildAzureCommand = string.Format( NodeConstants.PkgMgrRunBuildAzureCommandTemplate, packageManagerCmd); } } } if (IsBuildRequired(ctx) && string.IsNullOrEmpty(_nodeScriptGeneratorOptions.CustomBuildCommand) && string.IsNullOrEmpty(_nodeScriptGeneratorOptions.CustomRunBuildCommand) && string.IsNullOrEmpty(runBuildCommand) && string.IsNullOrEmpty(runBuildAzureCommand) && string.IsNullOrEmpty(runBuildLernaCommand) && string.IsNullOrEmpty(runBuildLageCommand)) { throw new NoBuildStepException( "Could not find either 'build' or 'build:azure' node under 'scripts' in package.json. " + "Could not find value for custom run build command using the environment variable " + "key 'RUN_BUILD_COMMAND'." + "Could not find tools for building monorepos, no 'lerna.json' or 'lage.config.js' files found."); } if (packageJson?.dependencies != null) { var depSpecs = ((JObject)packageJson.dependencies).ToObject <IDictionary <string, string> >(); _logger.LogDependencies( _commonOptions.PlatformName, nodePlatformDetectorResult.PlatformVersion, depSpecs.Select(d => d.Key + d.Value)); } if (packageJson?.devDependencies != null) { var depSpecs = ((JObject)packageJson.devDependencies).ToObject <IDictionary <string, string> >(); _logger.LogDependencies( _commonOptions.PlatformName, nodePlatformDetectorResult.PlatformVersion, depSpecs.Select(d => d.Key + d.Value), true); } string compressNodeModulesCommand = null; string compressedNodeModulesFileName = null; GetNodeModulesPackOptions(ctx, out compressNodeModulesCommand, out compressedNodeModulesFileName); if (!string.IsNullOrWhiteSpace(compressedNodeModulesFileName)) { manifestFileProperties[NodeConstants.NodeModulesFileBuildProperty] = compressedNodeModulesFileName; } bool pruneDevDependencies = ShouldPruneDevDependencies(ctx); string appInsightsInjectCommand = string.Empty; GetAppOutputDirPath(packageJson, manifestFileProperties); string customRegistryUrl = null; if (ctx.Properties != null) { ctx.Properties.TryGetValue(RegistryUrlPropertyKey, out customRegistryUrl); if (!string.IsNullOrWhiteSpace(customRegistryUrl)) { // Write the custom registry to the build manifest manifestFileProperties[$"{NodeConstants.PlatformName}_{RegistryUrlPropertyKey}"] = customRegistryUrl; } } string packageDir = null; if (ctx.Properties != null) { ctx.Properties.TryGetValue(PackageDirectoryPropertyKey, out packageDir); if (!string.IsNullOrWhiteSpace(packageDir)) { // Write the package directory to the build manifest manifestFileProperties[$"{PackageDirectoryPropertyKey}"] = packageDir; } } var scriptProps = new NodeBashBuildSnippetProperties { PackageRegistryUrl = customRegistryUrl, PackageDirectory = packageDir, PackageInstallCommand = packageInstallCommand, NpmRunBuildCommand = runBuildCommand, NpmRunBuildAzureCommand = runBuildAzureCommand, HasProdDependencies = hasProdDependencies, HasDevDependencies = hasDevDependencies, ProductionOnlyPackageInstallCommand = productionOnlyPackageInstallCommand, CompressNodeModulesCommand = compressNodeModulesCommand, CompressedNodeModulesFileName = compressedNodeModulesFileName, ConfigureYarnCache = configureYarnCache, YarnCacheFolderName = yarnCacheFolderName, PruneDevDependencies = pruneDevDependencies, AppInsightsInjectCommand = appInsightsInjectCommand, AppInsightsPackageName = NodeConstants.NodeAppInsightsPackageName, AppInsightsLoaderFileName = NodeAppInsightsLoader.NodeAppInsightsLoaderFileName, PackageInstallerVersionCommand = packageInstallerVersionCommand, RunNpmPack = _commonOptions.ShouldPackage, CustomBuildCommand = _nodeScriptGeneratorOptions.CustomBuildCommand, CustomRunBuildCommand = _nodeScriptGeneratorOptions.CustomRunBuildCommand, LernaRunBuildCommand = runBuildLernaCommand, InstallLernaCommand = installLernaCommand, LernaInitCommand = NodeConstants.LernaInitCommand, LernaBootstrapCommand = NodeConstants.LernaBootstrapCommand, InstallLageCommand = NodeConstants.InstallLageCommand, LageRunBuildCommand = runBuildLageCommand, }; string script = TemplateHelper.Render( TemplateHelper.TemplateResource.NodeBuildSnippet, scriptProps, _logger); return(new BuildScriptSnippet { BashBuildScriptSnippet = script, BuildProperties = manifestFileProperties, }); }