Skip to content
This repository has been archived by the owner on Dec 18, 2017. It is now read-only.

allow additional files to be included in the nupkg #2561

Merged
merged 2 commits into from
Aug 29, 2015

Conversation

analogrelay
Copy link
Contributor

fixes #848

blocked on aspnet/FileSystem#120 ... still waiting for a squirrel there ;). Anyone on this review should feel free to go review that and give me a squirrel there :P

With this change, the project.json can have a new packageFiles section, for example:

{
    "packageFiles": {
        "destination1/": "source1/**",
        "destination2/": "source2/**",
        "destination2/some_additional_file.txt": "source2a/somefile.txt",
        "destination3/": ["source3/a.txt", "source3/b.txt", "source4/c/**/*.ps1"]
    }
}

The value is a JSON object. Keys in this object (destination1, etc. in the above example) are destinations relative to the package root. P. If they end with a /, they are treated as directories, otherwise they are files. The associated value is one or more globbing patterns. If the globs end up pulling in multiple files, the destination on the left must be a directory, otherwise an error is reported (see tests for example). If the destination is a directory, the file name for each file is calculated using the stem of the globbing match (see aspnet/FileSystem#120).

Open Questions:

  1. Name of PackageFilesSource class is weird, but I want to keep the Line/Column info around for error reporting...
  2. Handling the "arity" of the source/destination pairs is still a little icky. Requiring that directories end with "/" seemed like the easiest because it allows us to have a clear error. Thoughts? That part can be tweaked both now, and after receiving user feedback in the remaining beta.

/cc @davidfowl @Tratcher @BrennanConroy @halter73 @lodejard

yield return new PhysicalPackageFile()
{
SourcePath = file.Path.Replace('/', Path.DirectorySeparatorChar),
TargetPath = Path.Combine(dir, file.Stem.Replace('/', Path.DirectorySeparatorChar))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might break in case of absolute, incorrect paths - two cases that comes to my mind are:

/Windows/ -->You will probably end up witch \Windows\file.txt path
// --> you will end up with \

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source paths come from globbing which has already processed them and made them absolute. And the target paths are used relative to the ZIP file being generated so the worst they can do is mess up a user's package. In either case, if the user types an incorrect path, they will get an incorrect result, which doesn't seem bad to me :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think file.Stem is always relative so you are right - we should be always relative to the ZIP file and then it is on the user to make sure that targets are correct.

@davidfowl
Copy link
Member

My eyes aren't used to destinations being on the left, it feels still feels odd.


public PackageFilesSource(IEnumerable<string> values, int line, int column)
{
Values = values.ToList().AsReadOnly();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all callers call an IList directly? If so change the input to list or array or something specific. This isn't a generic type that we want to expose to people is it?

@analogrelay
Copy link
Contributor Author

I suppose we could do destination on the right. It's a little weird to have globbing patterns as keys in a dictionary, but it's not awful.

packageBuilder.Save(fs);
_buildOptions.Reports.Quiet.WriteLine("{0} -> {1}", _currentProject.Name, Path.GetFullPath(nupkg));
}
bool packageSuccess = packDiagnostics.All(d => d.Severity != DiagnosticMessageSeverity.Error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!packDiagnostics.HasErrors()

@ChengTian
Copy link
Contributor

With the following configuration:

{
    "packageFiles": {
        "tools/": "A.txt",
        "./tools/": "B.txt",
        "arbitrary/../tools": "C.txt"
    }
}

The current implementation will copy all three .txt files into one tools folder, which looks fine.

However, with

{
    "packageFiles": {
        "tools/final.txt": "A.txt",
        "./tools/final.txt": "B.txt",
        "arbitrary/../tools/final.txt": "C.txt"
    }
}

The behavior is undefined because we are using Dictionary, which is unsorted. So we don't know which .txt file gets copied as the last one and overwrites all previous ones.

@moozzyk
Copy link
Contributor

moozzyk commented Aug 26, 2015

Should we even allow overwriting files by default? feels scary (--force option would be useful)

@analogrelay
Copy link
Contributor Author

I'd be ok with blocking files with duplicate final target paths.

@analogrelay
Copy link
Contributor Author

I'd also be OK with banning path-traversal characters in the target paths since they are unnecessary :)

@@ -233,12 +236,25 @@ internal static Project GetProjectFromStream(Stream stream, string projectName,

project.Dependencies = new List<LibraryDependency>();

// Files to be packed along with the project
var packInclude = rawProject.ValueAsJsonObject(PackIncludePropertyName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parse all of this lazily

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm doing so, but it means more of the JSON is retained in memory without being parsed down to smaller data structures. I'm not sure that's actually useful. Perhaps with the ProjectReader change we could make the amount of data loaded configurable and then only have dnu pack load this much but that seems like a larger change.

Anyway, I'll lazy it for now and we can discuss a better option later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps with the ProjectReader change we could make the amount of data loaded configurable and then only have dnu pack load this much but that seems like a larger change.

I'll look into that. I was thinking of a runtime project but this might be a better option. Either that or make it all lazy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a separate project class used by the runtime? That's not a bad idea either. Also, we should extract ProjectReader out into a package at some point (possibly just a shared source package). We'd still embed it in the runtime, but as @rynowak said it's useful in other situations.

@analogrelay
Copy link
Contributor Author

@davidfowl @moozzyk

@analogrelay
Copy link
Contributor Author

Travis failures are unrelated

_buildOptions.Reports.Quiet.WriteLine("{0} -> {1}", _currentProject.Name, Path.GetFullPath(nupkg));
}

if (symbolPackageBuilder.Files.Any())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What? No it isn't, it was in my original PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline diff looks weird, split diff is clearer. Regardless, this was in the PR from early on.

@analogrelay
Copy link
Contributor Author

@pranavkm @davidfowl

entries = archive.Entries.Select(e => e.FullName).Where(IsNotOpcMetadata).ToArray();
}

Assert.Equal(0, exitCode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you print the stdError if the exitCode is non-zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's already printed by the test.

@pranavkm
Copy link
Contributor

:shipit:

@analogrelay analogrelay merged commit 9e7a621 into dev Aug 29, 2015
@@ -64,6 +64,7 @@ var PROGRAM_FILES_X86 = '${Environment.GetFolderPath(Environment.SpecialFolder.P
var MSBUILD = '${Path.Combine(PROGRAM_FILES_X86, "MSBuild", "14.0", "Bin", "MSBuild.exe")}'
var VS_REDIST_ROOT = '${Path.Combine(PROGRAM_FILES_X86, @"Microsoft Visual Studio 14.0\VC\redist")}'
var WIN10_SDK_LIB = '${Path.Combine(PROGRAM_FILES_X86, @"Windows Kits\10\Lib")}'
var VS_ONECORE_ROOT = '${Path.Combine(PROGRAM_FILES_X86, @"Microsoft Visual Studio 14.0\VC\lib\onecore")}'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anurse - why was this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was in a situation where I did have the Windows SDK installed but still couldn't build for OneCore because I was missing files in this folder. I'll sync up with you in person.

@analogrelay analogrelay deleted the anurse/848-additional-files branch September 22, 2015 21:12
@andreasandreou
Copy link

any idea when this will be available?

@analogrelay
Copy link
Contributor Author

It should be available already, though the name was changed to packInclude.

@andreasandreou
Copy link

@anurse thank you, indeed you can include content using packInclude but there is still no way to get to import the content from package into the project which makes this pretty much useless.

@analogrelay
Copy link
Contributor Author

Correct, that's something tracked over in the dotnet/cli repo, since DNX is being retired: https://github.com/dotnet/cli/issues/66

@andreasandreou
Copy link

thank you very much for the follow up @anurse, this is very good news, will track referenced issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow additional files in the nupkg
7 participants