C#

279 次浏览

获取项目中全部 NuGet 包以及对应的 License

我们在日常 .NET Core 项目开发的过程中,经常需要获得整个解决方案中所有项目所引用的 NuGet 包的列表、对应的 License,甚至有时候出于法律的考量,我们需要检查 NuGet 包中所有递归引用的内部包的 License。

如果我们手动进行检查,工作量是巨大的,因此我编写了一个 PowerShell 脚本,来自动化完成这个工作。

基本原理

首先,基于 dotnet 命令自带的 list package 方法,及 –include-transitive 参数,来获取全部包引用的列表。
随后,通过 WebClient 下载对应的 License 文件。

使用方法

将 .ps1 文件放置到项目解决方案文件 (.sln) 所在位置并运行即可。

*

In the process of daily .NET Core project development, we often need to obtain a list of NuGet packages referenced by all projects in the solution, corresponding licenses, and sometimes for legal considerations, we need to check all licenses of recursion internal packages in each directly referenced NuGet packages.

If we check it manually, the workload is huge, so I wrote a PowerShell script to automate this task.

Fundamental

It’s based on the list package method that comes with the dotnet command, and the –include-transitive parameter, to obtain a list of all package references. And then, download the corresponding license file through WebClient.

Instructions

Place the .ps1 file in the location of the project solution file (.sln) and run it.

*

# Place the file to .sln folder, and run

dotnet list package --include-transitive > NuGetPackageList.txt

mkdir ".\licenses" > nul 2> nul
echo "Package ID,Package Version,Package Spec URL,License URL" > LicenseList.csv

Select-String "(>)\s+(\S+)\s+(\S+)\s+(\S+)*" NuGetPackageList.txt  |  Select @{Name="Id"; Expression = {$_.Matches.Groups[2]}}, @{Name="Version"; Expression = {$_.Matches.Groups[3]}}  |  Sort-Object -Property @{Expression="Id"; Descending=$false}, @{Expression="Version"; Descending=$false} -unique | % {

    $packageId = $_.Id;
    $packageIdLowerCase = $packageId.ToString().ToLower();
    $packageVersion = $_.Version;
    $packageSpecUrl = "https://api.nuget.org/v3-flatcontainer/$packageIdLowerCase/$packageVersion/$packageIdLowerCase.nuspec"

    Write-Host
    Write-Host("o> $packageId")
    Write-Host("  $packageVersion`n  $packageSpecUrl") -ForegroundColor Green 

    Try {  
        # Refer to https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-manifest-nuspec
        [xml]$packageSpec = (New-Object System.Net.WebClient).DownloadString($packageSpecUrl);
        $packageLicenseUrl = $packageSpec.package.metadata.licenseUrl;

        Write-Host("  $packageLicenseUrl") -ForegroundColor Green 
        echo "$packageId,$packageVersion,$packageSpecUrl,$packageLicenseUrl" >> LicenseList.csv
        
        Try {
            $filePath = (Join-Path (pwd) 'licenses\') + "$packageId.$packageVersion.txt";
            (New-Object System.Net.WebClient).DownloadFile($packageLicenseUrl, $filePath);
        }
        Catch [system.exception] {
            # Write-Host ($error[0].Exception);
            Write-Host ("!!> Could not download license file for $packageId $packageVersion") -ForegroundColor DarkMagenta
        }
    }
    Catch [system.exception] {
        # Write-Host ($error[0].Exception);
        Write-Host ("!!> Could not read license for $packageId $packageVersion") -ForegroundColor Red
        echo "$packageId,$packageVersion,$packageSpecUrl,(none)" >> LicenseList.csv
    }

}
1,362 次浏览

Squirrel Framework 查询入门 (1)

从 Squirrel Framework 1.0.15 起,我们拥有了 4 种 MongoDB / Cosmos DB 的查询形式,分别是 定制封装、Linq、Lambda 及 Mongo Database Object Command。今天我们通过一个最简单的例子,来介绍一下最常规的查询模式,体验 MongoDB 可以给我们带来的便捷。

如何获取并使用?


正式开始

假设我们在 MongoDB 或者 Microsoft Azure Cosmos DB 中有一个 TestDatabase,其中的 UserCollection 表中拥有许多的用户信息,我们希望得到:

在按照年龄从大到小排序的情况下,选取前三名,18 到 27 岁的老姑娘,并且英文名字中必须带字母 “h”。

啧啧。同时,由于我们每个 User 对象的数据都非常大,出于存储成本及数据传递成本的考虑,我只希望得到她们的中文名和联系电话。

如果我们在常规的 SQL 数据库中进行查询,只需编写如下 SQL 语句。


SELECT TOP 3 
  ChineseName AS Girl,
  MobilePhone AS Tel
FROM
  UserCollection
WHERE
  EnglishName LIKE "%h%"
  AND Gender = 1
  AND Age > 17
  AND Age < 28
ORDER BY
  Age DESC

那么对于 NoSQL 类型的 MongoDB 数据库,我们又该如何基于 Squirrel Framework 进行查询呢?这次我们以 1.0.15 版本最新的 Linq 方式进行查询。


        private dynamic LinqQuery()
        {
            var userCollection = this.userRepository.AsQueryable();
            var regex = new Regex("h", RegexOptions.IgnoreCase);

            var query = from u in userCollection
                        where regex.IsMatch(u.Name)
                                && u.Gender == false
                                && u.Age > 17
                                && u.Age < 28
                        orderby u.Age descending
                        select new { Girl = u.ChineseName, Tel = u.MobilePhone };

            return query.Take(3).ToList();
        }

        // Get the result
        var json = JsonHelper.Serialize(this.LinqQuery());


版本说明

2,080 次浏览
2,144 次浏览
1,829 次浏览

如何将 .NET DateTime 转换为 JavaScript Date – 形如:\/Date(1539953962642)\/

前言

在使用 ASP.NET MVC 开发 Web 程序时,对于 DateTime 类型的数据在 JSON 结果中,以类似于 “\/Date(1539953962642)\/” 的形式进行返回,那么这里中格式叫做什么呢?其中的数字的意义如何?

实际上这种数据格式叫做 Microsoft’s built-in JSON Date format,这不是任何一个通用规范的一部分,它是微软定义的一种格式。并且这里的数字并不是 .NET DateTime 的 Ticks!实际上这个值就是 TimeInMillis!


Ticks 和 TimeInMillis 有什么区别?

Ticks 一般是指从 0001-01-01 00:00:00.000 到现在的百纳秒计数,这个计数单位是 100 nanosecond(long 类型存储),.NET 平台使用 Ticks 方式记录时间(比如 [C#] DateTime.UtcNow.Ticks)。

TimeInMillis 一般是指从 1970-01-01 00:00:00.000 到现在的毫秒数,这个单位是 1 millisecond(long 类型存储),Java 和 JavaScript 使用 TimeInMillis 方式记录时间(比如 [JavaScript] Date.now())

所以,我们只需要通过正则表达式提取这个 Microsoft’s built-in JSON Date format 的值,直接应用于 JavaScript 即可。
Continue reading

2,752 次浏览

.NET Standard / Core 项目发布 NuGet 包并使包中的配置文件自动生成到 Bin 下

之前在如何创建 NuGet 包的文章中,曾经提到如何将配置文件(文件夹)包含到 NuGet 包中,并在用户安装了这个 NuGet 包并 build 自己工程后,自动将 Config 文件夹复制到 Bin 下。但是当时我并没有找到 .NET Standard 或 .NET Core 项目的配置方法,因此 Squirrel Framework 只能选择通过 .NET Framework 4.6.2 项目形式生成 NuGet 包(.NET Framework 下 NuGet 的配置方式请查看这篇文章《如何在 NuGet 发布自己的类库包》)。

不过最近有时间,通过半天的尝试终于将 4.6.2 的工程切换到 .NET Standard,这次的关键点在于不必自己去写 .nuspec 配置文件之后通过 dotnet pack 命令进行 build,而是改为直接通过编辑项目文件(.csproj)并通过 Visual Studio 在每次 build 时,自动完成 NuGet 包的生成。具体配置步骤如下:

Continue reading

1,791 次浏览
2,093 次浏览