PowerShell 7.x - قسمت دهم - بررسی مشکلات به همراه پرچم فرمت
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: دو دقیقه

خیلی از ابزارهای command line، براساس فلسفه‌ی bash تهیه شده‌اند؛ به این معنا که امکان استفاده‌ی مستقیم از bash، درون دستورات وجود دارد. به عنوان مثال فرض کنید میخواهیم لیست branchهای یک مخزن گیت را با کمک دستور زیر در خروجی، به صورت JSON نمایش دهیم. برای اینکار با یک جستجو شاید به این نتیجه برسید که از پرچم format در دستور git branch استفاده کنید: 
PS /> git branch --format='{"name":"%(refname:lstrip=2)"}' --list
در اینجا به گیت گفته‌ایم که یک فرمت سفارشی، برای خروجی در نظر بگیرد. میخواهیم خروجی، لیستی از آبجکت‌هایی باشد که شامل یک پراپرتی name با مقدار نام branch هستند. برای مقدار این پراپرتی، از یک placeholder مشخص استفاده شده‌است:  
%(refname:lstrip=2)
refname در اینجا به نام کامل branch اشاره میکند؛ با این تفاوت که رشته‌ی refs/heads که در ابتدای آن وجود دارد، برای حذف آن از lstrip=2 استفاده کرده‌ایم. در نهایت این چنین خروجی‌ایی برایمان نمایش داده خواهد شد: 
{"name":"main"}
{"name":"feature-branch-a"}
{"name":"feature-branch-b"}
,...
اما فرض کنید میخواهیم یک پراپرتی دیگر نیز با عنوان isMainBranch به این آبجکت اضافه کنیم. برای اینکار معمولاً از یک عبارت bash استفاده میشود: (با فرض اینکه main برنچ اصلی‌مان است) 
PS /> git branch --format='{"name":"%(refname:lstrip=2)","isMainBranch":'"$(if [[ $(git symbolic-ref --short HEAD) == "main" ]]; then echo true; else echo false; fi)"' }' --list
اما اگر این دستور را در PowerShell وارد کنید، با خطای زیر مواجه خواهید شد: 
ParserError:
Line |
   1 |  … --format='{"name":"%(refname:lstrip=2)","isMainBranch":'"$(if [[ $(gi …
     |                                                                 ~
     | Missing '(' after 'if' in if statement.
زیرا در اینجا از سینتکس bash، برای بررسی شرط استفاده کرده‌ایم. پارزر PowerShell هم بلافاصله بعد از دیدن $، انتظار دارد که بعد از if، از پرانتز استفاده کنیم. احتمالاً فکر میکنید که با escape کردن کاراکتر $، مشکل رفع میشود: 
'"`$(if [[ `$
اما در اینحالت همه چیز به عنوان string در نظر گرفته میشود و هیچ ارزیابی برای اجرای nested script رخ نمیدهد؛ در نتیجه خروجی اینچنین خواهد بود: 
{"name":"main","isMainBranch":$(if [[ $(git symbolic-ref --short HEAD) == main ]]; then echo true; else echo false; fi) }
{"name":"feature-branch-a","isMainBranch":$(if [[ $(git symbolic-ref --short HEAD) == main ]]; then echo true; else echo false; fi) }
{"name":"feature-branch-b","isMainBranch":$(if [[ $(git symbolic-ref --short HEAD) == main ]]; then echo true; else echo false; fi) }
برای رفع این مشکل باید به صورت کامل از PowerShell استفاده کنیم و JSON موردنظرمان را خودمان تهیه کنیم؛ یعنی بدون استفاده از format در گیت: 
$branches = git branch | ForEach-Object {
    $default = $false
    $activeBranch = git symbolic-ref --short HEAD
    $currentBranch = ($_.Replace("* ", " ")).Trim()
    if ($currentBranch -eq $activeBranch) {
        $default = $true
    }
    @{
        name            = $currentBranch
        isMainBranch = $default
    } | ConvertTo-Json
} | ConvertFrom-Json