<commit_before>param($app, $dir)

. "$psscriptroot\..\lib\core.ps1"
. "$psscriptroot\..\lib\manifest.ps1"
. "$psscriptroot\..\lib\description.ps1"

if(!$dir) {
    $dir = "$psscriptroot\..\bucket"
}
$dir = resolve-path $dir

$search = "*"
if($app) { $search = $app }

# get apps to check
$apps = @()
Get-ChildItem $dir "$search.json" | ForEach-Object {
    $json = parse_json "$dir\$($_.Name)"
    $apps += ,@(($_.Name -replace '\.json$', ''), $json)
}

$apps | ForEach-Object {
    $app, $json = $_
    write-host "$app`: " -nonewline

    if(!$json.homepage) {
        write-host "`nNo homepage set." -fore red
        return
    }
    # get description from homepage
    try {
        $wc = New-Object Net.Webclient
        $wc.Headers.Add('User-Agent', (Get-UserAgent))
        $home_html = $wc.downloadstring($json.homepage)
    } catch {
        write-host "`n$($_.exception.message)" -fore red
        return
    }

    $description, $descr_method = find_description $json.homepage $home_html
    if(!$description) {
        write-host -fore red "`nDescription not found ($($json.homepage))"
        return
    }

    $description = clean_description $description

    write-host "(found by $descr_method)"
    write-host "  ""$description""" -fore green

}
<commit_msg>Describe.ps1: Add parameter validation, format (#2993)<commit_after><#
.SYNOPSIS
    Search for application description on homepage.
.PARAMETER App
    Manifest name to search.
    Placeholders are supported.
.PARAMETER Dir
    Where to search for manifest(s).
#>
param(
    [String] $App = '*',
    [ValidateScript( {
        if (!(Test-Path $_ -Type Container)) {
            throw "$_ is not a directory!"
        }
        $true
    })]
    [String] $Dir = "$PSScriptRoot\..\bucket"
)

. "$PSScriptRoot\..\lib\core.ps1"
. "$PSScriptRoot\..\lib\manifest.ps1"
. "$PSScriptRoot\..\lib\description.ps1"

$Dir = Resolve-Path $Dir
$Queue = @()

Get-ChildItem $Dir "$App.json" | ForEach-Object {
    $manifest = parse_json "$Dir\$($_.Name)"
    $Queue += , @(($_.Name -replace '\.json$', ''), $manifest)
}

$Queue | ForEach-Object {
    $name, $manifest = $_
    Write-Host "$name`: " -NoNewline

    if(!$manifest.homepage) {
        Write-Host "`nNo homepage set." -ForegroundColor Red
        return
    }
    # get description from homepage
    try {
        $wc = New-Object Net.Webclient
        $wc.Headers.Add('User-Agent', (Get-UserAgent))
        $home_html = $wc.DownloadString($manifest.homepage)
    } catch {
        Write-Host "`n$($_.Exception.Message)" -ForegroundColor Red
        return
    }

    $description, $descr_method = find_description $manifest.homepage $home_html
    if(!$description) {
        Write-Host "`nDescription not found ($($manifest.homepage))" -ForegroundColor Red
        return
    }

    $description = clean_description $description

    Write-Host "(found by $descr_method)"
    Write-Host "  ""$description""" -ForegroundColor Green
}
{'fraction_non_alphanumeric': 0.16604666892120393, 'fraction_numerical': 0.0037199864727764627, 'mean_word_length': 2.72544080604534, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3659927', 'n_tokens_mistral': 1007, 'n_tokens_neox': 963, 'n_words': 213}