From f94ee533fa662723432196a09a9c6e44b3301dac Mon Sep 17 00:00:00 2001 From: Rashil Gandhi Date: Sun, 13 Nov 2022 20:13:12 +0530 Subject: [PATCH 1/2] Add function to detect CI environment --- lib/core.ps1 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/core.ps1 b/lib/core.ps1 index bc0365eb03..850421d728 100644 --- a/lib/core.ps1 +++ b/lib/core.ps1 @@ -1212,6 +1212,34 @@ function Out-UTF8File { } } +function Get-CIEnvironment { + foreach ($ci_env in @{ + 'APPVEYOR' = 'AppVeyor' + 'TF_BUILD' = 'Azure Pipelines' + 'bamboo.buildKey' = 'Bamboo' + 'BUILDKITE' = 'Buildkite' + 'CIRCLECI' = 'Circle CI' + 'CIRRUS_CI' = 'Cirrus CI' + 'CODEBUILD_BUILD_ID' = 'CodeBuild' + 'GITHUB_ACTIONS' = 'Github Actions' + 'GITLAB_CI' = 'GitLab CI' + 'HEROKU_TEST_RUN_ID' = 'Heroku CI' + 'TEAMCITY_VERSION' = 'TeamCity' + 'TRAVIS' = 'Travis CI' + }.GetEnumerator()) { + if (-not [String]::IsNullOrEmpty((Get-Item "Env:/$($ci_env.Key)" -ErrorAction Ignore).Value)) { + return $ci_env.Value + } + } + foreach ($ci_env in 'BUILD_ID', 'CI') { + if (-not [String]::IsNullOrEmpty((Get-Item "Env:/$($ci_env)" -ErrorAction Ignore).Value)) { + return 'generic' + } + } + + return "" +} + ################## # Core Bootstrap # ################## From d86b7c72e281375e8209f8f23fdedfee790cd9a6 Mon Sep 17 00:00:00 2001 From: Rashil Gandhi Date: Sun, 13 Nov 2022 20:17:15 +0530 Subject: [PATCH 2/2] Disable analytics for now --- bin/scoop.ps1 | 13 ++++ libexec/scoop-analytics.ps1 | 128 ++++++++++++++++++++++++++++++++++++ libexec/scoop-config.ps1 | 3 + 3 files changed, 144 insertions(+) create mode 100644 libexec/scoop-analytics.ps1 diff --git a/bin/scoop.ps1 b/bin/scoop.ps1 index 6d96c68b2f..03ba3400c5 100644 --- a/bin/scoop.ps1 +++ b/bin/scoop.ps1 @@ -44,6 +44,19 @@ switch ($subCommand) { exec 'help' @($subCommand) } else { exec $subCommand $arguments + + # Run analytics + $anltcs_time = get_config ANALYTICS_TIMESTAMP + if ($subCommand -ne 'analytics' -and + -not (get_config ANALYTICS_DISABLE) -and + -not (Get-CIEnvironment) -and + ([String]::IsNullOrEmpty($anltcs_time) -or (New-TimeSpan $anltcs_time ([System.DateTime]::Now)).TotalDays -ge 7)) { + # Start-Process -NoNewWindow ` + # -FilePath $(if ($PSEdition -eq 'Core') { 'pwsh.exe' } else { 'powershell.exe' }) ` + # -ArgumentList "-NoProfile", "-File $PSScriptRoot\scoop.ps1", "analytics" ` + # -RedirectStandardOutput "$Env:TEMP\scoop_analytics_out.txt" ` + # -RedirectStandardError "$Env:TEMP\scoop_analytics_err.txt" + } } } default { diff --git a/libexec/scoop-analytics.ps1 b/libexec/scoop-analytics.ps1 new file mode 100644 index 0000000000..5fae81590f --- /dev/null +++ b/libexec/scoop-analytics.ps1 @@ -0,0 +1,128 @@ +# Usage: scoop analytics +# Summary: Collects and sends Scoop usage analytics to a remote server +# Help: This is an internal command. It is used to collect and send usage analytics +# to a remote server, at an interval of 7 days. The following data is collected: +# - Randomly generated (one-time) anonymous ID +# - Machine info +# - OS build number +# - OS Architecture +# - PowerShell Desktop version +# - PowerShell Core version +# - Scoop version +# - Apps installed from public buckets (private apps are filtered out) +# - Name +# - Version +# - Last updated +# - Source +# - Architecture +# - User or Global installation +# - Installation status +# - Public buckets (private buckets are filtered out) +# - Name +# - Source +# - Last updated +# - Manifest count + +. "$PSScriptRoot\..\lib\json.ps1" # 'ConvertToPrettyJson' + +if ([String]::IsNullOrEmpty((get_config ANALYTICS_ID))) { + set_config ANALYTICS_ID (New-Guid).Guid | Out-Null +} +$def_arch = Get-DefaultArchitecture +$known_sources = foreach ($item in (known_bucket_repos).PSObject.Properties) { $item.Value } + +function Test-PublicSource($source) { + # Known sources + if ($source -in $known_sources) { + return $true + } + # Local file paths, SSH remotes, and remotes with usernames + if ($source -match '^/[A-Za-z]:/|^[A-Za-z]:/|^\./|^\.\./|file:/|ssh:/|@') { + return $false + } + return $true +} + + +$stats = [ordered]@{} +$stats.id = get_config ANALYTICS_ID + +$stats.machine = [ordered]@{ + Build = [System.Environment]::OSVersion.Version.ToString() + Arch = $def_arch + Desktop = (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name 'PowerShellVersion').PowerShellVersion + Core = if (Get-Command pwsh -ErrorAction Ignore) { + (Get-Item (Get-Command pwsh).Source).VersionInfo.ProductVersionRaw.ToString() + } else { + "" + } + Scoop = if (Test-Path "$PSScriptRoot\..\.git") { + $branch = (Get-Content "$PSScriptRoot\..\.git\HEAD").Replace('ref: ', '') + "$(Get-Content (Join-Path "$PSScriptRoot\..\.git" $branch)) ($($branch.Split('/')[-1]))" + } elseif (Test-Path "$PSScriptRoot\..\CHANGELOG.md") { + (Select-String '^## .*([\d]{4}-[\d]{2}-[\d]{2})' "$PSScriptRoot\..\CHANGELOG.md").Matches.Groups[1].Value + } else { + "" + } +} + +$bucket_names = @() +$stats.buckets = @() +foreach ($item in list_buckets) { + # Filter out private buckets + if (Test-PublicSource $item.Source) { + $stats.buckets += $item + $bucket_names += $item.Name + } +} + +$stats.apps = @() +foreach ($item in @(& "$PSScriptRoot\scoop-list.ps1" 6>$null)) { + # Filter out private apps + if ($item.Source -notin $bucket_names) { + continue + } + + $info = $item.Info -Split ', ' + + $newitem = [ordered]@{} + $newitem.Name = $item.Name + $newitem.Version = $item.Version + $newitem.Source = $item.Source + $newitem.Updated = $item.Updated + $newitem.Global = 'Global install' -in $info + $newitem.Arch = if ('64bit' -in $info -and '64bit' -ne $def_arch) { + '64bit' + } elseif ('32bit' -in $info -and '32bit' -ne $def_arch) { + '32bit' + } elseif ('arm64' -in $info -and 'arm64' -ne $def_arch) { + 'arm64' + } else { + $def_arch + } + $newitem.Status = if ('Held package' -in $info) { + 'Held' + } elseif ('Install failed' -in $info) { + 'Failed' + } else { + 'OK' + } + + $stats.apps += $newitem +} + +$payload = $stats | ConvertToPrettyJSON + +try { + Invoke-RestMethod -Method Post ` + -Uri 'https://analytics.scoop.sh/post' ` + -Body $payload ` + -ContentType "application/json" + set_config ANALYTICS_TIMESTAMP ([System.DateTime]::Now.ToString('o')) | Out-Null +} catch { + Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ + Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription +} + +exit 0 + diff --git a/libexec/scoop-config.ps1 b/libexec/scoop-config.ps1 index 09487da7c5..b58baaa1fa 100644 --- a/libexec/scoop-config.ps1 +++ b/libexec/scoop-config.ps1 @@ -115,6 +115,9 @@ # Nightly version is formatted as 'nightly-yyyyMMdd' and will be updated after one day if this is set to $true. # Otherwise, nightly version will not be updated unless `--force` is used. # +# analytics_disable: $true|$false +# Set this to $true to disable sending anonymous usage analytics. +# # ARIA2 configuration # ------------------- #