بررسی بهبودهای پروسه‌ی Build در دات‌نت 8
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: یک دقیقه

در نگارش‌های اخیر دات‌نت، NET CLI. به همراه تغییرات قابل توجهی بوده‌است که در این مطلب و نظرات آن، موارد مهم این تغییرات را بررسی خواهیم کرد.

console logger بهبود یافته‌ی دات‌نت 8

یکی از تغییرات بسیار جالب توجه و مفید NET CLI. در دات‌نت 8، امکان دسترسی به خروجی لاگ‌های ساختار یافته‌ی اعمال خط فرمان آن است:

اگر پروژه‌ی خود را با استفاده از دستور dotnet build، کامپایل می‌کنید، خروجی پیش‌فرض این دستور خط فرمان، کلی و بدون ارائه‌ی جزئیات است؛ اما می‌توان آن‌را در دات‌نت 8، به شکل تصویر فوق، تغییر داد و به این مزایا رسید:

  • امکان مشاهده‌ی زمان کامپایل هر قسمت به صورت جداگانه
  • امکان مشاهده‌ی پویای درصد انجام عملیات
  • امکان مشاهده‌ی جزئیات کامپایل هر target framework به صورت مجزا
  • دسترسی به یک خروجی رنگی و زیباتر

این خروجی را که به صورت پیش‌فرض فعال نیست، می‌توان به دو صورت:

الف) سراسری و با اجرای دستور PowerShell زیر:

[Environment]::SetEnvironmentVariable("MSBUILDTERMINALLOGGER", "auto", "User")

که متغیر محیطی MSBUILDTERMINALLOGGER را به auto تنظیم می‌کند،

ب) و یا با استفاده از سوئیچ tl-- به ازای هر دستور dotnet build، به صورت جداگانه‌ای فعال کرد:

dotnet build --tl

یک نکته: این قابلیت جالب و مهم، در دات نت 9، به صورت پیش‌فرض فعال است و نیازی به تنظیم خاصی ندارد.

  • #
    ‫۱ ماه قبل، جمعه ۲۶ مرداد ۱۴۰۳، ساعت ۱۵:۳۷

    یک نکته‌ی تکمیلی: تعدیل خطاهای بررسی امنیتی بسته‌های نیوگت در حالت کار offline در دات‌نت 8

    اگر در پروژه‌ی خود، تنظیم گزارش اخطارها را به صورت خطا، فعال کرده باشید:

    <PropertyGroup>
       <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    </PropertyGroup>

    و ... از دات‌نت 8 هم استفاده می‌کنید، هربار با صدور فرمان dotnet build و یا dotnet restore، با خطای زیر مواجه خواهید شد:

    warning NU1900: Error occurred while getting package vulnerability data: (more information)

    البته یکبار که اطلاعات امنیتی بسته‌ها ذخیره شدند، ممکن است در طول یک روز دیگر شاهد این خطا نباشید، اما ... دوباره فردا تکرار خواهد شد و اگر بخواهید offline کار کنید، این خطا واقعا مشکل ساز می‌شود!

    برای کنترل آن یا می‌توان به صورت زیر عمل کرد:

    <PropertyGroup>
        <NuGetAudit>false</NuGetAudit>
    </PropertyGroup>

    که بررسی امنیتی بسته‌های نیوگت را کاملا غیرفعال می‌کند و یا می‌توان به صورت زیر، این بررسی را فقط به حالت Release خلاصه کرد:

    <PropertyGroup>
      <NuGetAudit>true</NuGetAudit>
      <NuGetAuditMode>all</NuGetAuditMode>
      <NuGetAuditLevel>low</NuGetAuditLevel>
      <WarningsNotAsErrors Condition="'$(Configuration)' != 'Release'">
        $(WarningsNotAsErrors);NU1900;NU1901;NU1902;NU1903;NU1904
      </WarningsNotAsErrors>
    </PropertyGroup>

    در این حالت هرچند اخطارهای NU1900 و دردسترس نبودن اینترنت ظاهر می‌شوند، اما دیگر به‌عنوان خطا پردازش نخواهند شد (چون در قسمت WarningsNotAsErrors ذکر شده‌اند) و پروسه‌ی build را متوقف نمی‌کنند.

  • #
    ‫۱ ماه قبل، شنبه ۲۷ مرداد ۱۴۰۳، ساعت ۱۹:۰۱

    یک نکته‌ی تکمیلی: چگونه آنالایزرهای بسیار کند را پیدا کنیم؟!

    پس از غنی‌سازی پروژه با تعدادی Roslyn Analyzer، با اولین موردی که مواجه خواهیم شد، بالا رفتن زمان کامپایل است؛ گاهی از اوقات تا حدی که کار کامپایل، چند دقیقه طول می‌کشد. در این حالت شاید این سؤال مطرح شود که کدامیک از این آنالایزرهای اضافه شده، بیشترین زمان را به خودش اختصاص داده؟

    برای پاسخ به این سؤال، فقط کافی است پروژه را با سوئیچ bl/، کامپایل کنیم:

    dotnet build /bl

    خروجی آن که یک فایل باینری است به نام msbuild.binlog، توسط برنامه‌ی «MSBuild Binary and Structured Log Viewer» قابل مشاهده‌است:

    پس از باز کردن این فایل در برنامه‌ی یاد شده، می‌توان ذیل قسمت Analyzer summary (مانند تصویر فوق)، زمان صرف شده‌ی توسط هر آنالایزر را مشاهده کرد و در صورت نیاز، موارد زمانبر را از پروژه حذف کرد.

    یا حتی می‌توانید اجرای تمام آنالایزرها را برای حالت دیباگ، غیرفعال کنید:

    dotnet run -p:RunAnalyzers=false
  • #
    ‫۲۹ روز قبل، یکشنبه ۲۸ مرداد ۱۴۰۳، ساعت ۱۹:۲۱

    یک نکته‌ی تکمیلی: چگونه تاریخ Build را به اسمبلی برنامه اضافه کنیم؟

    شاید علاقمند باشید که بجای نمایش شماره نگارش برنامه، تاریخ Build آن‌را در قسمتی خاص، نمایش دهید. برای اینکار می‌توان یک ویژگی جدید را به صورت زیر به اسمبلی برنامه اضافه کرد:

    [AttributeUsage(AttributeTargets.Assembly)]
    public sealed class BuildDateAttribute : Attribute
    {
        public BuildDateAttribute(string buildDateTime) => BuildDateTime = buildDateTime;
    
        public string BuildDateTime { get; }
    }

    تا در زمان کامپایل برنامه، فایل obj\Debug\net8.0\DntSite.Web.AssemblyInfo.cs را به این صورت تکمیل کند:

    using System;
    using System.Reflection;
    
    [assembly: DNTCommon.Web.Core.BuildDateAttribute("1403.05.28.15.17")]
    [assembly: System.Reflection.AssemblyCompanyAttribute("DntSite.Web")]
    [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]

    مقدار دهی این این ویژگی جدید، در زمان Build و توسط تنظیمات زیر در فایل csproj. برنامه انجام می‌شود:

    <Project>
      <ItemGroup>
            <AssemblyAttribute Include="DNTCommon.Web.Core.BuildDateAttribute">
                <_Parameter1>$([System.DateTime]::Now.ToString("yyyy.MM.dd.HH.mm"))</_Parameter1>
            </AssemblyAttribute>
      </ItemGroup>

    با استفاده از AssemblyAttribute می‌توان پارامترهای دلخواهی را به ویژگی Include شده، ارسال کرد؛ برای مثال، تاریخ جاری سیستم را. اگر تعداد پارامترهای سازنده بیشتر بود، می‌توان Parameter2_ و Parameter3_ و ... را هم تنظیم کرد.

    همین اندازه تنظیم برای اضافه شدن خودکار این ویژگی جدید به اسمبلی نهایی برنامه کافی است (و همانطور که عنوان شد، محل درج خودکار اولیه‌ی آن، در فایل AssemblyInfo.cs پوشه‌ی obj برنامه‌است). برای خواندن و نمایش آن هم می‌توان به صورت زیر عمل کرد:

    public static class BuildDateAttributeExtensions
    {
        public static string? GetBuildDateTime(this Assembly? assembly) =>
            assembly?.GetCustomAttribute<BuildDateAttribute>()?.BuildDateTime ??
            assembly?.GetName().Version?.ToString();
    }

    برای نمونه می‌توان اطلاعات BuildDateAttribute اسمبلی جاری را به صورت زیر استخراج کرد:

    private static string? GetVersionInfo() => Assembly.GetExecutingAssembly().GetBuildDateTime();