Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Self-contained NuGet Packages - Icons should be embedded in Packages #352

Closed
johnataylor opened this issue Apr 3, 2015 · 91 comments
Closed
Assignees
Milestone

Comments

@johnataylor
Copy link
Member

Package Icon should be able to come form inside the package.
It should be possible to put a path in the iconUrl that is relative to the package.

@ChrisSfanos ChrisSfanos added this to the 3.1-Beta milestone Apr 7, 2015
@veleek
Copy link

veleek commented Jun 2, 2015

Note: Transferred from issue on CodePlex - Packages containing Icon and License

Packages containing Icon and License

Problem Statement

Currently, the NuGet schema only allows the package author to specify the LicenseUrl and IconUrl as external URLs for the license and icon respectively. This puts the burden on the developer to find a place to host those files and update the NuSpec with their locations.

Solution

The NuGet Gallery should support unpacking a license and icon within the package folder both explicitly specified and by convention.

Details

Convention Based Approach

The convention based approach is very simple.

File Description
Icon.png An Icon.png at the root of the package will be unpacked and used as the icon for the package
License.txt A license.txt file at the root of the package will be used as the license

Explicit Reference

Alternatively, we can support explicit references using the file:// prefixed URLs relative to the package root. For example:

<iconUrl>file://content/images/nugetIcon.png</iconUrl>

This grabs the file from the content/images folder of the package and hosts it on the server. This is useful in cases where the icon is also hosted.

Device Specific Icon Images

There a multiple places where icons are displayed.

  • NuGet Dialog (32x32)
  • NuGet.org packages list (50x50)
  • NuGet.org package details page (100x100)

We should consider a convention that allows developers to include an icon specific to each of these devices.

Proposal

Use a file extension for each.

  • Icon_dialog.png (32x32)
  • Icon_list.png (50x50)
  • Icon_details.png (100x100)

@csharpfritz
Copy link
Contributor

We see some customers unable to view icons as the web location of the icon image is blocked by their corporate firewall. Possible solution could be to download and serve the images from NuGet.org as a resource at the same URI as the package when an image media type is requested

@maartenba
Copy link
Contributor

-> NuGet/NuGetGallery#2613

@xavierdecoster xavierdecoster changed the title Package Icon should be able to come form inside the package Package Icon should be able to come from inside the package Oct 9, 2015
@xavierdecoster
Copy link
Member

To support an embedded package icon in the nupkg, it seems we only need the 32x32 icon. All other images are only served on the gallery and don't need to be in the package.

As this issue is about supporting an embedded icon in the package, it sounds to me that a convention-based icon.png in the package root could be sufficient?
IconUrl is an optional nuspec element, so not sure if we should make it required to support an embedded icon.
Perhaps we should simply fallback from IconUrl to icon.png (if present) to default nuget icon?

@maartenba
Copy link
Contributor

That's an entirely different discussion. All we need is package icon proxying over www.nuget.org.

@xavierdecoster
Copy link
Member

Nope, your discussion is here: NuGet/NuGetGallery#2613
Related,
but not the topic of this client issue 😊
So, on topic, how about this client issue?

@yishaigalatzer yishaigalatzer modified the milestones: 3.4, 3.3.0 Nov 25, 2015
@yishaigalatzer yishaigalatzer added Type:Feature Priority:3 Issues under consideration. With enough upvotes, will be reconsidered to be added to the backlog. labels Nov 25, 2015
@yishaigalatzer
Copy link

Proposal

Use a file extension for each.

Icon_dialog.png (32x32)
Icon_list.png (50x50)
Icon_details.png (100x100)

We should specify the size in the icon name instead

icon32x32.png
icon50x50.png
icon100x100.png

We need to discuss if we require all of them, can they be updated later etc.

@Allann
Copy link

Allann commented Feb 23, 2016

I'd prefer to see the scale convention used by win8 manifests used here too. this would mean that brand images can be re-used and we don't need to create even more files named differently.

@hesantan
Copy link

hesantan commented Jun 1, 2016

We should specify the size in the icon name instead

icon32x32.png
icon50x50.png
icon100x100.png

We need to discuss if we require all of them, can they be updated later etc.

I think that just requiring the biggest required size is enough. That image can be downsized to all the other necessary resolutions.

@ghuntley
Copy link

ghuntley commented Aug 19, 2016

  • Yes please, this would be fantastic.
  • Please only require single size (biggest) and do your conversion using NuGet.exe at the pack stage which then creates the needed sizes for display in the NuGet.org gallery and Visual Studio/Xamarin Studio which uses this by default.
  • By using the embedded image by default in Visual Studio/Xamarin Studio it prevents network profiling/leakage of which packages a company/developer uses. Fallback to ImageUrl if the embedded image is not found (provides legacy transition path)
  • Potentially use the most excellent library ImageResizer.NET within NuGet.exe?

@ohadschn
Copy link

Downsizing is suboptimal. There is no escape from separate files if you want decent quality. Even the official purple ".NET" icon doesn't look that great in its downsized 32x32 form.

Having the option to only provide one size and have the rest downsized is great, as long as there's a way to provide files for the different sizes separately.

@adamralph
Copy link

The image in package details on nuget.org is 128x128, not 100x100.

image

Although, in order to have that showing with full fidelity on a high DPI display, you need a larger image. E.g. I run my display scaled at 200%. Notice the difference between a 128x128 image and a 256x256 image, even though the dimensions within the page are still 128x128:

image

For this reason, I am gradually changing all my NuGet packages to have 256x256 logos instead of 128x128. Of course, that only solves this precisely for high DPI scaling at 200%, and any other level of scaling, e.g. 125%, 150% or greater than 200% will still be suboptimal. One thing that would solve all these issues, forever, is SVG support, since that eliminates the need for image scaling entirely.

BTW - the dimensions in the package list are 48x48, not 50x50:

image

@SimonCropp
Copy link

+1 for svg as the default

@angamuthu-g
Copy link

hi,
I'm facing issue while creating windows installer. this is the issue i'm getting

electron-windows-installer:spawn Spawning mono /var/www/html/Extraction/node_modules/electron-winstaller/vendor/nuget.exe pack /tmp/si-11702-14710-a00hji.hot6ueg66r/app.nuspec -BasePath dist/app-win32-ia32 -OutputDirectory /tmp/si-11702-14710-a00hji.hot6ueg66r -NoDefaultExcludes +3ms
No dice: Failed with exit code: 1
Output:

Unhandled Exception: System.TypeLoadException: Could not load type 'NuGet.Program' from assembly 'NuGet, Version=2.8.50926.602, Culture=neutral, PublicKeyToken=null'.
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeLoadException: Could not load type 'NuGet.Program' from assembly 'NuGet, Version=2.8.50926.602, Culture=neutral, PublicKeyToken=null'.
WARNING: The runtime version supported by this application is unavailable.
Using default runtime: v2.0.50727

@RehanSaeed
Copy link

RehanSaeed commented Sep 25, 2019

Is it possible to refer to an image in a directory outside the project? It would be very useful to do so if you have multiple NuGet packages in a solution:

Root
    Images
        Icon.png
    Source
        Package1
            Package1.csproj
        Package2
            Package2.csproj
<PropertyGroup Label="Package">
    <!-- This is what I've tried: -->
    <PackageIcon>file://../../Images/Icon.png</PackageIcon>
    <PackageIcon>../../Images/Icon.png</PackageIcon>
</PropertyGroup>

<ItemGroup Label="Files">
    <None Include="..\..\Images\Icon.png" Pack="true" PackagePath=""/>
</ItemGroup>

However, all I've tried so far produces errors.

UPDATE

I've figured it out. This seems to work:

<PropertyGroup Label="Package">
    <PackageIcon>Icon.png</PackageIcon>
</PropertyGroup>

@anangaur
Copy link
Member

anangaur commented Sep 25, 2019

I think this was supported. @karann-msft would know better. And I saw the UPDATE after I typed 😁

@rrelyea
Copy link
Contributor

rrelyea commented Sep 25, 2019

Glad you found the right way.

The package path put the image in the root of the package.
The package icon needs to refer to the matching location.

Please take a look at the docs and suggest any improvements that would help with this case.

@anangaur anangaur changed the title Package Icons should be embedded in Packages, instead of an external URL. Self-contained NuGet Packages - Icons should be embedded in Packages Sep 25, 2019
@fluffynuts
Copy link

After seeing this, I really wanted to package an icon in my NExpect package(s). However, nuget pack is bailing out with the error:

The element 'metadata' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd' has invalid child element 'icon' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'. List of possible elements expected: 'requireLicenseAcceptance, licenseUrl, frameworkReferences, tags, repository, contentFiles, packageTypes, copyright, references, license, serviceable, developmentDependency, iconUrl, dependencies, frameworkAssemblies' in namespace 'http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd'. This validation error occurred in a 'icon' element.

My Package.nuspec contains the following:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<package>
  <metadata>
    <id>NExpect</id>
    <version>1.0.158</version>
    <title>NExpect</title>
    <authors>Davyd McColl</authors>
    <owners>Davyd McColl</owners>
    <description>&#xD;&#xD;&#xD;&#xD;
    Unit-test Framework-agnostic Expect-style assertions for .NET&#xD;&#xD;&#xD;&#xD;
    </description>
    <releaseNotes>&#xD;&#xD;&#xD;&#xD;
    </releaseNotes>
    <summary>&#xD;&#xD;&#xD;&#xD;
    Provides Expect() syntax for doing assertions in .NET. Framework-agnostic, throwing&#xD;&#xD;&#xD;&#xD;
    UnmetExpectationExceptions for failures. Assertion exception type can be overridden at run-time.&#xD;&#xD;&#xD;&#xD;
    NExpect has grammar inspired by Chai and extensibility inspired by Jasmine.&#xD;&#xD;&#xD;&#xD;
    </summary>
    <language>en-US</language>
    <projectUrl>https:/fluffynuts/NExpect</projectUrl>
    <icon>icon.png</icon>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">BSD-3-Clause</license>
    <copyright>Copyright 2017</copyright>
    <dependencies>
      <group targetFramework="net452"/>
    </dependencies>
    <references/>
    <tags/>
  </metadata>
  <files>
    <file src="icon.png" target="" />
    <file src="bin\BuildForRelease\net452\NExpect.dll" target="lib\net452"/>
    <file src="bin\BuildForRelease\net452\NExpect.pdb" target="lib\net452"/>
    <file src="bin\BuildForRelease\netstandard2.0\NExpect.xml" target="lib\net452"/>
    <file src="bin\BuildForRelease\netstandard2.0\NExpect.dll" target="lib\netstandard2.0"/>
    <file src="bin\BuildForRelease\netstandard2.0\NExpect.xml" target="lib\netstandard2.0"/>
    <file src="bin\BuildForRelease\netstandard2.0\NExpect.pdb" target="lib\netstandard2.0"/>
    <file src="bin\BuildForRelease\netstandard2.0\NExpect.deps.json" target="lib\netstandard2.0"/>
  </files>
</package>

what am I doing wrong?

@devlead
Copy link

devlead commented Oct 13, 2019

@fluffynuts you need NuGet.exe version 5.3, guess it's not blessed yet, as it's not available on nuget ( https://www.nuget.org/packages/NuGet.CommandLine/ ).

But you can download it from https://www.nuget.org/downloads

@fluffynuts
Copy link

Ah, thanks -- I did a nuget update -self and got 5.2.something; I'll try with 5.3, but I'll only really be able to switch over when 5.3 is blessed as build & release are automated, including nuget update -self to ensure latest tooling at release.

@rrelyea
Copy link
Contributor

rrelyea commented Oct 13, 2019

Looks like our blessing we did of 5.3 missed a step. We’ll fix on Monday.

@adamralph
Copy link

@fluffynuts are you unable to use dotnet pack? The latest SDK contains the new icon bits.

@StingyJack
Copy link
Contributor

@rrelyea - can you also please publish working nuspec.xsd's?

It would be nice to get some schema based intellisense in VS for nuspec files.

@fluffynuts
Copy link

@adamralph whilst I'm in the process of converting to modern projects (Project Sdk projects rather than ones mentioning toolsversion) where possible, I still have a bunch of legacy projects and afaik, dotnet <anything> isn't going to work on them?
Anyways:

  1. I can wait until Monday (:
  2. I've updated the very project I've just been working in -- had to work around multi-targeting (using Mono to provide net452), so it's nearly ready for conversion, and I'll get on it some time soon; however, I have another larger project which produces 33 packages, and that's not likely to go all-modern in a hurry (I'm not even sure how to modernis a .vbproj, and there is one in there)

This hasn't stopped my release -- I just reference the icon by url from GitHub. I was just wanting to use the new mechanism seeing as I was in the neighborhood -- I just got an icon from an #hacktoberfest PR 👍

@zivkan
Copy link
Member

zivkan commented Nov 23, 2020

@SimonCropp's comment has 17 upvotes (only 👍 counts). GitHub doesn't have any way for us to transfer upvotes from one issue to another (let alone a comment from an issue). So, anyone interested please upvote this issue on adding SVG support (original/first comment, not my comment). At this time, that issue only has 3 upvotes (probably because it was closed years ago, but I just reopened it).

@StingyJack
Copy link
Contributor

@zivkan - Can you make a feature request through official channels for that kind of thing? I would think it would be something you would have a better time requesting than the GenPop. If not or you dont want to wait, I imagine scripting something would be the way to aggregate votes across comments and issues for the same request.

only 👍 counts

Lets not have any digital gerrymandering or "chads"; 👍 ❤️ 😆 🚀 and :Hooray: are all positive reactions and should all be counted as upvotes. Excluding them would be removing > 30% of the current votes.

@zivkan
Copy link
Member

zivkan commented Nov 23, 2020

Microsoft may have bought GitHub, but they still operate as an external company, and I have no inside knowledge or contacts. I don't even know where external customers can request new features.

Lets not have any digital gerrymandering or "chads"; 👍 ❤️ 😆 🚀 and :Hooray: are all positive reactions and should all be counted as upvotes. Excluding them would be removing > 30% of the current votes.

GitHub doesn't provide a way to sort issues by "all positive reactions", at least that I'm aware of. Therefore, while we prioritize work on a number of factors, on GitHub I look at open issues sorted by 👍 , as that appears to be the most commonly used reaction. While it would be nice to count all positive reactions, we need to be pragmatic and it's something we can't easily take into account right now. If I'm wrong, I'd be happy for someone to educate me so we can better take all reactions into account.

@StingyJack
Copy link
Contributor

StingyJack commented Nov 23, 2020

I'd be happy for someone to educate me so we can better take all reactions into account.

For that specific comment...

$ErrorActionPreference = 'Stop'

$headers = @{"Accept"="application/vnd.github.squirrel-girl-preview+json";}
$url = "https://api.github.com/repos/NuGet/home/issues/comments/261106692/reactions" 
$resp = Invoke-WebRequest -Headers $headers -Uri $url -UseBasicParsing
$rawResp = $resp.Content | ConvertFrom-Json
$rawResp | Group-Object -Property content | Sort-Object -Descending -Property Count | Format-Table -Property Count,Name

#####results####
Count Name  
----- ----  
   17 +1    
    5 heart 
    2 hooray
    1 laugh 

I opened a ticket with GH support on how to do this through the UI, they said its currently not possible via the UI but forwarded the request to the product team with a link to the comment above by @zivkan explaining the need.

@rudyscoggins
Copy link

Is a side effect of this change that the Nuget package download now includes the icon file? We released a new version of our package using the new and tag in the nuspec and now our client downloads have our logo.png showing up in their projects.

If that is correct, is there a way to override this? A typical user for us wouldn't care if the nuget package manager properly shows the icon, but it's annoying for them to have our logo force its way into their project file structure. I would still want our package to have a logo on the Nuget Package Manager online search.

@fluffynuts
Copy link

fluffynuts commented Feb 4, 2021

@rudyscoggins my package.nuspec contains the line:

<file src="icon.png" target="" />

which I assume is the secret sauce for not having the icon deployed to the consumer (ie target="")

@adamralph
Copy link

The icon will only appear in consuming projects if the package has been incorrectly created.

@rudyscoggins
Copy link

rudyscoggins commented Feb 4, 2021

Ah, so I am doing something wrong. I'm not sure what though. I have the target=""...

Here's my nuspec file. Could you take a quick glance to see if something is wrong? The image lives at my project file root:

<?xml version="1.0"?>
<package >
  <metadata>
      <id>mySDK</id>
      <version>20.96.2.1</version>
      <title>mySDK 20.96</title>
      <authors>Me</authors>
      <owners>Me</owners>
      <requireLicenseAcceptance>false</requireLicenseAcceptance>
	<icon>MyLogo.png</icon>	
      <description>Here's an SDK</description>
	<summary>Here's a summary of the SDK</summary>
      <releaseNotes>this is released</releaseNotes>
      <copyright>Copyright 2020</copyright>
	<license type="expression">Apache-2.0</license>
      <tags>My SDK</tags>
	<dependencies>		
	</dependencies>
    </metadata>
  <files>    
    <file src="MyLogo.png" target="" />    
  </files>
</package>

@adamralph
Copy link

Are you creating your package with an explicit nuspec?

If possible, I advise moving away from that and allowing the SDK to create the nuspec for you. FWIW, I just have a PackageIcon element in my csproj and the rest Just Works. — https:/adamralph/bullseye/blob/d11fea517642b5f56f19d5a6963f4a818b698cc9/Bullseye/Bullseye.csproj#L11

If I dig into the nupkg, the generated nuspec looks like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>Bullseye</id>
    <version>3.7.0</version>
    <authors>Bullseye</authors>
    <owners>Bullseye</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">Apache-2.0</license>
    <licenseUrl>https://licenses.nuget.org/Apache-2.0</licenseUrl>
    <projectUrl>https:/adamralph/bullseye</projectUrl>
    <description>Runs a target dependency graph.</description>
    <releaseNotes>https:/adamralph/bullseye/blob/master/CHANGELOG.md</releaseNotes>
    <repository type="git" url="https:/adamralph/bullseye" commit="89fc1b57063c44e21bc851f218f166ca63a6e846" />
    <dependencies>
      <group targetFramework=".NETStandard2.0" />
    </dependencies>
    <icon>bullseye.png</icon>
  </metadata>
</package>

Note that there is no file element for the icon file. It's file is just sitting in the root folder in the nupkg archive.

@adamralph
Copy link

Oh, there is also this — https:/adamralph/bullseye/blob/d11fea517642b5f56f19d5a6963f4a818b698cc9/Bullseye/Bullseye.csproj#L26 — so I guess it's not quite as simple as it could be.

@rudyscoggins
Copy link

Thanks all for the help and sanity checks! I really appreciate it and it helped me solve the problem.

Turns out I thought I needed to include the image file in the project. After experimenting, I realized it SHOULDN'T be included in the project and is only meant to reside in the nuget package. This is what caused it to be distributed. Hopefully this helps someone else.

@adamralph my upload process needs to be revised, relying more on self made scripts than nuget standards. I'll incorporate your suggestion for moving more into the SDK. Thanks!

@PawcioCNCProfi
Copy link

This puts the burden on the developer to find a place to host those files and update the NuSpec with their locations.

I don't get it. What kind of burden is this? If you want to update an icon you would update it one place... Now I actually do need to specify the icon anyway and copy the icon to every project which suppose to be packed and make sure the icon have the same version in all those places... Is this a less burden? What kind of improvement is this?
If you really need the icon to be embedded, why not just download the icon form the iconUrl and place it in the package during pack, instead of the "'iconUrl' element is deprecated..." nonsense?

@SimonCropp
Copy link

@PawcioCNCProfi

why not just download the icon form the iconUrl and place it in the package during pack

because that would be a breaking change. ie for anyone expecting the old behavior of being able to change the icon at the target url and have the package be rendered with the new icon

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

No branches or pull requests