private void WriteApplicationProjectJsonFile(string applicationFolder) { var projectFileName = Path.GetFileName(_project.ProjectFilePath); var appScriptProjectFile = Path.Combine( applicationFolder, projectFileName); File.Copy( _project.ProjectFilePath, appScriptProjectFile, overwrite: true); // If the source file is readonly, the destination will be readonly too // so remove the readonly attribute FileOperationUtils.MakeWritable(appScriptProjectFile); Runtime.Project appProject; Runtime.Project.TryGetProject(appScriptProjectFile, out appProject); ModifyJson(appScriptProjectFile, projectFile => { projectFile["entryPoint"] = _project.Name; projectFile["loadable"] = false; var dependencies = new JObject(); projectFile[nameof(dependencies)] = dependencies; dependencies[_project.Name] = _project.Version.ToString(); }); _packageBuilder.Files.Add(new PhysicalPackageFile() { SourcePath = appScriptProjectFile, TargetPath = Path.Combine(CommandsFolderName, projectFileName) }); }
public void Write(string filePath, LockFile lockFile) { // Make sure that if the lock file exists, it is not readonly if (File.Exists(filePath)) { FileOperationUtils.MakeWritable(filePath); } using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) { Write(stream, lockFile); } }
public int Execute() { if (Directory.Exists(HttpCacheDirectory)) { Reports.Information.WriteLine($"Clearing cache directory {HttpCacheDirectory}"); try { FileOperationUtils.DeleteFolder(HttpCacheDirectory); Reports.Information.WriteLine("Cache cleared."); } catch (Exception e) { Reports.Error.WriteLine($"Unable to clear cache directory: {e.Message}"); return(1); } } return(0); }
// Creates a temporary project with the specified package as dependency private string CreateTemporaryProject(string installFolder, string packageName, string packageVersion) { var tempFolderName = Guid.NewGuid().ToString("N"); var tempFolderFullPath = Path.Combine(installFolder, tempFolderName); // Delete if exists already FileOperationUtils.DeleteFolder(tempFolderFullPath); Directory.CreateDirectory(tempFolderFullPath); WriteVerbose("Temporary folder name: {0}", tempFolderFullPath); var projectFileFullPath = Path.Combine(tempFolderFullPath, "project.json"); File.WriteAllText( projectFileFullPath, string.Format( @"{{ ""dependencies"":{{ ""{0}"":""{1}"" }} }}", packageName, packageVersion)); return(projectFileFullPath); }
public async Task <bool> Execute(string packageId, string packageVersion) { // 0. Resolve the actual package id and version var packageIdAndVersion = await ResolvePackageIdAndVersion(packageId, packageVersion); if (packageIdAndVersion == null) { WriteError($"Failed to install {packageId}"); return(false); } packageId = packageIdAndVersion.Item1; packageVersion = packageIdAndVersion.Item2; WriteVerbose("Resolved package id: {0}", packageId); WriteVerbose("Resolved package version: {0}", packageVersion); // 1. Get the package without dependencies. We cannot resolve them now because // we don't know the target frameworks that the package supports FeedOptions.TargetPackagesFolder = _commandsRepository.PackagesRoot.Root; var temporaryProjectFileFullPath = CreateTemporaryProject(FeedOptions.TargetPackagesFolder, packageId, packageVersion); var packageFullPath = Path.Combine( _commandsRepository.PackagesRoot.Root, _commandsRepository.PathResolver.GetPackageDirectory(packageId, new SemanticVersion(packageVersion))); if (OverwriteCommands) { if (Directory.Exists(packageFullPath)) { WriteInfo($"Deleting {packageFullPath}"); FileOperationUtils.DeleteFolder(packageFullPath); Directory.Delete(packageFullPath); } } try { RestoreCommand.RestoreDirectories.Add(temporaryProjectFileFullPath); if (!await RestoreCommand.Execute()) { return(false); } } finally { var folderToDelete = Path.GetDirectoryName(temporaryProjectFileFullPath); FileOperationUtils.DeleteFolder(folderToDelete); Directory.Delete(folderToDelete); } if (!ValidateApplicationPackage(packageFullPath)) { return(false); } var packageAppFolder = Path.Combine( packageFullPath, InstallBuilder.CommandsFolderName); // 2. Now, that we have a valid app package, we can resolve its dependecies RestoreCommand.RestoreDirectories.Clear(); RestoreCommand.RestoreDirectories.Add(packageAppFolder); if (!await RestoreCommand.Execute()) { return(false); } // 3. Dependencies are in place, now let's install the commands if (!InstallCommands(packageId, packageFullPath)) { return(false); } return(true); }
private bool InstallCommands(string packageId, string appPath) { string commandsFolder = Path.Combine(appPath, InstallBuilder.CommandsFolderName); IEnumerable <string> allAppCommandsFiles; if (RuntimeEnvironmentHelper.IsWindows) { allAppCommandsFiles = Directory.EnumerateFiles(commandsFolder, "*.cmd"); } else { // We have cmd files and project.*.json files in the same folder allAppCommandsFiles = Directory.EnumerateFiles(commandsFolder, "*.*") .Where(cmd => !cmd.EndsWith(".cmd") && !cmd.EndsWith(".json")) .ToList(); } var allAppCommands = allAppCommandsFiles .Select(cmd => Path.GetFileNameWithoutExtension(cmd)) .ToList(); IEnumerable <string> conflictingCommands; if (OverwriteCommands) { conflictingCommands = new string[0]; } else { // Conflicting commands are only the commands not owned by this application conflictingCommands = allAppCommands.Where(appCmd => { var commandOwner = _commandsRepository.FindCommandOwner(appCmd); return(commandOwner != null && !packageId.Equals(commandOwner.Id, StringComparison.OrdinalIgnoreCase)); }); } if (conflictingCommands.Any()) { WriteError(string.Format( "The application commands cannot be installed because the following commands already exist: {0}. No changes were made. Rerun the command with the --overwrite switch to replace the existing commands.", string.Join(", ", conflictingCommands))); return(false); } var installPath = Path.GetFullPath(_commandsRepository.Root.Root); foreach (string commandFileFullPath in allAppCommandsFiles) { string commandFileName = RuntimeEnvironmentHelper.IsWindows ? Path.GetFileName(commandFileFullPath) : Path.GetFileNameWithoutExtension(commandFileFullPath); string commandScript; if (RuntimeEnvironmentHelper.IsWindows) { commandScript = string.Format( "@\"%~dp0{0}\" %*", commandFileFullPath.Substring(installPath.Length)); } else { commandScript = string.Format( "\"$(dirname $0){0}\" $@", commandFileFullPath.Substring(installPath.Length)); } string scriptFilePath = Path.Combine(installPath, commandFileName); File.WriteAllText(scriptFilePath, commandScript); if (!RuntimeEnvironmentHelper.IsWindows) { FileOperationUtils.MarkExecutable(commandFileFullPath); FileOperationUtils.MarkExecutable(scriptFilePath); } } var installedCommands = allAppCommandsFiles.Select(cmd => Path.GetFileNameWithoutExtension(cmd)); WriteInfo("The following commands were installed: " + string.Join(", ", installedCommands)); return(true); }
public void DnuRestore_ExecutesScripts(string flavor, string os, string architecture) { bool isWindows = TestUtils.CurrentRuntimeEnvironment.OperatingSystem == "Windows"; var environment = new Dictionary <string, string> { { "DNX_TRACE", "0" }, }; var expectedPreContent = @"""one"" ""two"" "">three"" ""four"" "; var expectedPostContent = @"""five"" ""six"" ""argument seven"" ""argument eight"" "; string projectJsonContent; string scriptContent; string scriptName; if (isWindows) { projectJsonContent = @"{ ""frameworks"": { ""dnx451"": { } }, ""scripts"": { ""prerestore"": [ ""script.cmd one two > pre"", ""script.cmd ^>three >> pre && script.cmd ^ four >> pre"" ], ""postrestore"": [ ""\""%project:Directory%/script.cmd\"" five six > post"", ""\""%project:Directory%/script.cmd\"" \""argument seven\"" \""argument eight\"" >> post"" ] } }"; scriptContent = @"@echo off :argumentStart if ""%~1""=="""" goto argumentEnd echo ""%~1"" shift goto argumentStart :argumentEnd"; scriptName = "script.cmd"; } else { projectJsonContent = @"{ ""frameworks"": { ""dnx451"": { } }, ""scripts"": { ""prerestore"": [ ""script one two > pre"", ""script.sh \\>three >> pre; ./script.sh four >> pre"" ], ""postrestore"": [ ""\""%project:Directory%/script\"" five six > post"", ""\""%project:Directory%/script.sh\"" \""argument seven\"" \""argument eight\"" >> post"" ] } }"; scriptContent = @"#!/usr/bin/env bash set -o errexit for arg in ""$@""; do printf ""\""%s\""\n"" ""$arg"" done"; scriptName = "script.sh"; } var projectStructure = $@"{{ '.': ['project.json', '{ scriptName }'] }}"; var runtimeHomePath = _fixture.GetRuntimeHomeDir(flavor, os, architecture); using (var testEnv = new DnuTestEnvironment(runtimeHomePath, projectName: "Project Name")) { var projectPath = testEnv.ProjectPath; DirTree.CreateFromJson(projectStructure) .WithFileContents("project.json", projectJsonContent) .WithFileContents(scriptName, scriptContent) .WriteTo(projectPath); FileOperationUtils.MarkExecutable(Path.Combine(projectPath, scriptName)); string output; string error; var exitCode = DnuTestUtils.ExecDnu( runtimeHomePath, subcommand: "restore", arguments: null, stdOut: out output, stdErr: out error, environment: environment, workingDir: projectPath); Assert.Equal(0, exitCode); Assert.Empty(error); Assert.Contains("Executing script 'prerestore' in project.json", output); Assert.Contains("Executing script 'postrestore' in project.json", output); var preContent = File.ReadAllText(Path.Combine(projectPath, "pre")); Assert.Equal(expectedPreContent, preContent); var postContent = File.ReadAllText(Path.Combine(projectPath, "post")); Assert.Equal(expectedPostContent, postContent); } }
private bool TryResolveReferences(out XDocument resolutionResults, out string errorMessage) { resolutionResults = new XDocument(); errorMessage = string.Empty; if (!File.Exists(MsBuildPath)) { errorMessage = string.Format("Unable to locate {0}", MsBuildPath.Red().Bold()); return(false); } // Put ReferenceResolver.xml and intermediate result files into a temporary dir var tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tempDir); try { _referenceResolverPath = Path.Combine(tempDir, ReferenceResolverFileName); var assembly = typeof(WrapCommand).GetTypeInfo().Assembly; var embeddedResourceName = "Microsoft.Dnx.Tooling.compiler.resources." + ReferenceResolverFileName; using (var stream = assembly.GetManifestResourceStream(embeddedResourceName)) { File.WriteAllText(_referenceResolverPath, stream.ReadToEnd()); } resolutionResults.Add(new XElement("root")); var projectFiles = new List <string> { Path.GetFullPath(InputFilePath) }; var intermediateResultFile = Path.Combine(tempDir, Path.GetRandomFileName()); for (var i = 0; i != projectFiles.Count; i++) { var properties = new[] { string.Format("/p:CustomAfterMicrosoftCommonTargets=\"{0}\"", _referenceResolverPath), string.Format("/p:ResultFilePath=\"{0}\"", intermediateResultFile), string.Format("/p:Configuration={0}", Configuration), "/p:DesignTimeBuild=true", "/p:BuildProjectReferences=false", "/p:_ResolveReferenceDependencies=true" // Dump entire assembly reference closure }; var msBuildArgs = string.Format("\"{0}\" /t:ResolveAndDump {1}", projectFiles[i], string.Join(" ", properties)); Reports.Verbose.WriteLine("Resolving references for {0}", projectFiles[i].Bold()); Reports.Verbose.WriteLine(); Reports.Verbose.WriteLine("Command:"); Reports.Verbose.WriteLine(); Reports.Verbose.WriteLine("\"{0}\" {1}", MsBuildPath, msBuildArgs); Reports.Verbose.WriteLine(); Reports.Verbose.WriteLine("MSBuild output:"); Reports.Verbose.WriteLine(); var startInfo = new ProcessStartInfo() { UseShellExecute = false, FileName = MsBuildPath, Arguments = msBuildArgs, RedirectStandardOutput = true, RedirectStandardError = true }; var process = Process.Start(startInfo); var stdOut = process.StandardOutput.ReadToEnd(); var stdErr = process.StandardError.ReadToEnd(); process.WaitForExit(); Reports.Verbose.WriteLine(stdOut); if (process.ExitCode != 0) { errorMessage = string.Format("Failed to resolve references for {0}", projectFiles[i].Red().Bold()); return(false); } var projectXDoc = XDocument.Parse(File.ReadAllText(intermediateResultFile)); foreach (var item in GetItemsByType(projectXDoc.Root, type: "ProjectReference")) { var relativePath = item.Attribute("evaluated").Value; var fullPath = PathUtility.GetAbsolutePath(projectFiles[i], relativePath); if (!projectFiles.Contains(fullPath)) { projectFiles.Add(fullPath); } } resolutionResults.Root.Add(projectXDoc.Root); } } finally { FileOperationUtils.DeleteFolder(tempDir); } return(true); }