diff --git a/src/Microsoft.DotNet.Tools.Publish/Program.cs b/src/Microsoft.DotNet.Tools.Publish/Program.cs index 9de5e254c..4709c47c4 100644 --- a/src/Microsoft.DotNet.Tools.Publish/Program.cs +++ b/src/Microsoft.DotNet.Tools.Publish/Program.cs @@ -127,6 +127,8 @@ namespace Microsoft.DotNet.Tools.Publish { exitCode = PublishForUnix(context, outputPath); } + + CopyContents(context, outputPath); Reporter.Output.WriteLine($"Published to {outputPath}".Green().Bold()); return exitCode; @@ -220,9 +222,74 @@ exec ""$DIR/corerun"" ""$DIR/{context.ProjectFile.Name}.exe"" $*"; var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix); File.Copy(coreConsole, outputExe, overwrite: true); + return 0; } + private static void CopyContents(ProjectContext context, string outputPath) + { + var sourceFiles = context.ProjectFile.Files.GetFilesForBundling(); + Copy(sourceFiles, context.ProjectDirectory, outputPath); + } + + private static void Copy(IEnumerable sourceFiles, string sourceDirectory, string targetDirectory) + { + if (sourceFiles == null) + { + throw new ArgumentNullException(nameof(sourceFiles)); + } + + sourceDirectory = EnsureTrailingSlash(sourceDirectory); + targetDirectory = EnsureTrailingSlash(targetDirectory); + + foreach (var sourceFilePath in sourceFiles) + { + var fileName = Path.GetFileName(sourceFilePath); + + var targetFilePath = sourceFilePath.Replace(sourceDirectory, targetDirectory); + var targetFileParentFolder = Path.GetDirectoryName(targetFilePath); + + // Create directory before copying a file + if (!Directory.Exists(targetFileParentFolder)) + { + Directory.CreateDirectory(targetFileParentFolder); + } + + File.Copy( + sourceFilePath, + targetFilePath, + overwrite: true); + + // clear read-only bit if set + var fileAttributes = File.GetAttributes(targetFilePath); + if ((fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + { + File.SetAttributes(targetFilePath, fileAttributes & ~FileAttributes.ReadOnly); + } + } + } + + private static string EnsureTrailingSlash(string path) + { + return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar); + } + + private static string EnsureTrailingCharacter(string path, char trailingCharacter) + { + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + // if the path is empty, we want to return the original string instead of a single trailing character. + if (path.Length == 0 || path[path.Length - 1] == trailingCharacter) + { + return path; + } + + return path + trailingCharacter; + } + private static void PublishFiles(IEnumerable files, string outputPath) { foreach (var file in files) diff --git a/src/Microsoft.Extensions.ProjectModel/Files/ProjectFilesCollection.cs b/src/Microsoft.Extensions.ProjectModel/Files/ProjectFilesCollection.cs index f7fc5a1c2..ab56d43dc 100644 --- a/src/Microsoft.Extensions.ProjectModel/Files/ProjectFilesCollection.cs +++ b/src/Microsoft.Extensions.ProjectModel/Files/ProjectFilesCollection.cs @@ -12,7 +12,7 @@ namespace Microsoft.Extensions.ProjectModel.Files public class ProjectFilesCollection { public static readonly string[] DefaultCompileBuiltInPatterns = new[] { @"**/*.cs" }; - public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json" }; + public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json", @"**/project.json", @"**/project.lock.json" }; public static readonly string[] DefaultPreprocessPatterns = new[] { @"compiler/preprocess/**/*.cs" }; public static readonly string[] DefaultSharedPatterns = new[] { @"compiler/shared/**/*.cs" }; public static readonly string[] DefaultResourcesBuiltInPatterns = new[] { @"compiler/resources/**/*", "**/*.resx" }; @@ -138,17 +138,15 @@ namespace Microsoft.Extensions.ProjectModel.Files get { return SharedPatternsGroup.SearchFiles(_projectDirectory).Distinct(); } } - public IEnumerable GetFilesForBundling(bool includeSource, IEnumerable additionalExcludePatterns) + public IEnumerable GetFilesForBundling(IEnumerable additionalExcludePatterns = null) { var patternGroup = new PatternGroup(ContentPatternsGroup.IncludePatterns, - ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns), + ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns ?? new List()), ContentPatternsGroup.IncludeLiterals); - if (!includeSource) + + foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup) { - foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup) - { - patternGroup.ExcludeGroup(excludedGroup); - } + patternGroup.ExcludeGroup(excludedGroup); } return patternGroup.SearchFiles(_projectDirectory);