Esempio n. 1
0
        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)
            });
        }
Esempio n. 2
0
        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);
            }
        }
        // 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);
        }
Esempio n. 4
0
        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 = "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);
        }
Esempio n. 5
0
        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);
            }
        }
        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

            if (string.IsNullOrEmpty(FeedOptions.TargetPackagesFolder))
            {
                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);
        }