Powershell: как разбить, сделать математику и формат - PullRequest
2 голосов
/ 15 февраля 2020

Я ищу 1-вкладыш, который выглядит примерно так:

(gitversion | ConvertFrom-Json).SemVer.split('.') | [string]::Format("{0}.{1}.{2}",$_[0],$_[1] + 1,$_[2]) | git tag $_

Итак, сейчас у меня есть 0.1.0, и я хочу 1 вкладыш, который будет сопоставлять его с: 0.2.0

Я уверен, что гуру в PS может быстро справиться с этим

Ответы [ 3 ]

4 голосов
/ 15 февраля 2020

Вы можете прочитать полностью json, использовать Major, Minor и Patch номера версии и обновить в зависимости от того, что вас интересует ... patch, minor или major.

Я использую foreach-object для доступа ко всем свойствам json, хотя доступен только один. 1-вкладыш :

gitversion | ConvertFrom-Json | % { "$($_.Major).$($_.Minor + 1).$($_.Patch)" } | % { git tag $_ }

Как% / ForEach-Object может работать с несколькими хранилищами

Если на пути, по которому вы запускаете gitversion, есть только один репозиторий, он всегда даст вам один объект. (gitversion терпит неудачу с ошибками, когда вы запускаете это в каталоге, в котором нет репозитория git.)

Я хотел бы подчеркнуть, что это будет прекрасно работать в вашем сценарии, где есть только Версия Major, Minor и Patch. В случаях, когда SemVersion имеет значение "SemVer":"0.1.0", это нормально. Но если вы заинтересованы в том, чтобы сохранить PreReleaseTag и в следующей версии (и не удалять теги alpha / beta et c), вы также можете включить PreReleaseTagWithDa sh в свой вывод. например, теги предварительной версии: "SemVer":"0.1.0-alpha.915"

gitversion | ConvertFrom-Json | % { "$($_.Major).$($_.Minor + 1).$($_.Patch)$($_.PreReleaseTagWithDash)" } | % { git tag $_ }

Примеры JSON-файлов gitversion

  • В dev или других ветках можно ожидать изменения в semVer включая предварительные выпуски тегов.
{
  "Major":0,
  "Minor":1,
  "Patch":0,
  "PreReleaseTag":"alpha.915",
  "PreReleaseTagWithDash":"-alpha.915",
  "PreReleaseLabel":"alpha",
  "PreReleaseNumber":915,
  "WeightedPreReleaseNumber":915,
  "BuildMetaData":"",
  "BuildMetaDataPadded":"",
  "FullBuildMetaData":"Branch.dev.Sha.888xxx.xxx888",
  "MajorMinorPatch":"0.1.0",
  "SemVer":"0.1.0-alpha.915",
  "LegacySemVer":"0.1.0-alpha915",
  "LegacySemVerPadded":"0.1.0-alpha0915",
  "AssemblySemVer":"0.1.0.0",
  "AssemblySemFileVer":"0.1.0.0",
  "FullSemVer":"0.1.0-alpha.915",
  "InformationalVersion":"0.1.0-alpha.915+Branch.dev.Sha.888xx.xx888",
  "BranchName":"dev",
  "Sha":"888xx.xx888",
  "ShortSha":"7a1152f",
  "NuGetVersionV2":"0.1.0-alpha0915",
  "NuGetVersion":"0.1.0-alpha0915",
  "NuGetPreReleaseTagV2":"alpha0915",
  "NuGetPreReleaseTag":"alpha0915",
  "VersionSourceSha":"88xxx.xx88",
  "CommitsSinceVersionSource":915,
  "CommitsSinceVersionSourcePadded":"0915",
  "CommitDate":"2019-12-06"
}
  • От основной ветки обычно можно ожидать semver = major.minor.patch.
{
  "Major":0,
  "Minor":1,
  "Patch":0,
  "PreReleaseTag":"",
  "PreReleaseTagWithDash":"",
  "PreReleaseLabel":"",
  "PreReleaseNumber":"",
  "WeightedPreReleaseNumber":"",
  "BuildMetaData":0,
  "BuildMetaDataPadded":"0000",
  "FullBuildMetaData":"0.Branch.master.Sha.9999xxx....xxx999",
  "MajorMinorPatch":"0.1.0",
  "SemVer":"0.1.0",
  "LegacySemVer":"0.1.0",
  "LegacySemVerPadded":"0.1.0",
  "AssemblySemVer":"0.1.0.0",
  "AssemblySemFileVer":"0.1.0.0",
  "FullSemVer":"0.1.0+0",
  "InformationalVersion":"0.1.0+0.Branch.master.Sha.999xxx...xxx999",
  "BranchName":"master",
  "Sha":"86b0be929a84ba7e9b2a463e7dbdc9a3c9325dc1",
  "ShortSha":"86b0be9",
  "NuGetVersionV2":"0.1.0",
  "NuGetVersion":"0.1.0",
  "NuGetPreReleaseTagV2":"",
  "NuGetPreReleaseTag":"",
  "VersionSourceSha":"999xxx...xxx999",
  "CommitsSinceVersionSource":0,
  "CommitsSinceVersionSourcePadded":"0000",
  "CommitDate":"2018-02-18"
}

ПРИМЕЧАНИЕ : Я не проверял это с несколькими git хранилищами в одном месте. Это решение будет работать, если на пути, по которому вы работаете, есть только хранилище.

3 голосов
/ 16 февраля 2020

Примечание: В приведенных ниже решениях предполагается, что строка представление, такое как 0.1.0, должно быть проанализировано ; как выясняется, утилита JSON, которая gitversion имеет отдельных компонентов с номером версии , таких как Major, Minor, ..., которые Ответ Джавада опирается на; однако даже использование отдельных свойств для синтеза выходных данных string может быть затруднительным, если необходимо сохранить все компоненты версии semver.


Для решения Надежный и удобный, используйте тип [semver] (System.Management.Automation.SemanticVersion), который PowerShell [Core] 6 + предлагает (команда распространяется на несколько строки для удобства чтения):

Вы можете просто привести строку версии, такую ​​как 0.1.0 к [semver], получив объект с цифра c .Major, .Minor и .Patch свойства, наряду с другими; из него можно создать новый [semver] экземпляр с измененной минорной версией и всеми другими свойствами, передаваемыми через:

(gitversion | ConvertFrom-Json).FullSemVer | foreach { 
   $v = [semver] $_;
   [semver]::new($v.Major, ($v.Minor+1), $v.Patch, $v.PreReleaseLabel, $v.BuildLabel) 
  } | foreach { 
        git tag $_ 
      }

foreach - встроенный псевдоним для командлета ForEach-Object.
Что выводит первая команда foreach, это [semver] объект , а не строка, но неявно передавая такой объект stringizes it, что дает желаемое представление.

Вышеуказанное гарантирует, что все компоненты semver -совместимой строки версии сохраняются на выходе , в частности, включая поля метаданных pre-release и build-метки, если таковые имеются (например,
1.0.0-alpha+001).


Если ваш номер версии строки всегда состоят из 2 - 4 цифр c -только компонентов (например, 1.0, 1.0.2, 1.0.2.10), вы можете использовать Вместо этого [version] (System.Version), который также доступен в Windows PowerShell (версии PowerShell 5.1 и ниже):

'0.1.0.34' | foreach { 
    $v = [version] $_; $newMinor = $v.Minor + 1
    if ($v.Build -ne -1 -and $v.Revision -ne -1) { [version]::new($v.Major, $newMinor, $v.Build, $v.Revision) }
    elseif ($v.Build -ne -1) { [version]::new($v.Major, $newMinor, $v.Build) }
    else {[version]::new($v.Major, $newMinor) }
   } | foreach { 
        git tag $_ 
      }

Обратите внимание на - к сожалению - необходимость выборочно использовать различные перегрузки конструкторов [version], что является следствием асимметрии проекта: неуказанные компоненты версии (для необязательных компонентов) поля build и revision) по умолчанию для заполнителя -1, но передача этих заполнителей в 4-компонентный конструктор не поддерживается .


Примечание: Преимущество в Вышеуказанное решение состоит в том, что вы получаете объект представлений номеров версий, которые облегчают программную c обработку в целом.

  • Однако вызывает недоумение тот факт, что ни [semver], ни [version] сами не предлагают методов для увеличения номеров версий, которые они представляют.

Если все, что вам нужно, это строка представление измененного номера версии, то также возможно краткое синтаксический анализ текста на основе регулярных выражений , что снова PowerShell [Core ] 6.2+ делает проще, потому что основанный на регулярных выражениях оператор -replace там поддерживает script-block замены на основе (см. Связанный ответ, как это сделать это в Windows PowerShell ):

(gitversion | ConvertFrom-Json).FullSemVer | foreach { 
   $_ -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
  } | foreach { 
        git tag $_ 
      }

Варианты регулярного выражения для приращения 3 компонентов номера версии (конечные метки предварительного выпуска и сборки будут сохранены):

  • основной номер (например, 2.0.9 -> 3.0.9):

    • '2.0.9' -replace '\d+(?=\..+)', { 1 + [int] $_.Value }
  • несовершеннолетний номер (как указано выше; 2.0.9 -> 2.1.9)):

патч номер (третий компонент; 2.0.9 -> 2.0.10):

  • '2.0.9' -replace '(?<=^\d+\.\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }

Предостережение : Предполагается, что целевой компонент версии присутствует во входной строке; например при попытке увеличить компонент patch во входной строке '2.0' будет не работать; эта хрупкость является еще одной причиной, чтобы предпочесть объектный подход через [semver].

1 голос
/ 15 февраля 2020

Если я правильно понял, вы хотите добавить 1 ко второму номеру. Я мог бы sh Я мог бы сделать $ a.minor + = 1, но тип [версия] доступен только для чтения.

$a = '0.1.0'
$nums = $a.split('.')
'{0}.{1}.{2}' -f $nums[0], ([int]$nums[1] + 1), $nums[2]

0.2.0

Или

$a = '0.1.0'
$nums = $a -split '\.'
([int]$nums[1])++
$nums -join '.'

0.2.0

Или

$a = '0.1.0'
$nums = $a.split('.')
([int]$nums[1])++
'{0}.{1}.{2}' -f $nums

0.2.0

Я также пробовал версию -replace для PS6 с блоком сценариев, но это стало сложным.

См. Также Увеличение версии в текстовом файле

Вот еще один вариант, но ему требуется powershell 6 для -replace с блоком сценариев. Я использую регулярные выражения с положительным прогнозом и положительным прогнозом, поэтому я заменяю только число, а не 2 точки на каждой стороне. Это будет работать только с 3 числами, если вы не хотите увеличить 2 средних числа на 1, смеется. Это, безусловно, квалифицируется как однострочник.

'0.11.0' -replace '(?<=\.)\d+(?=\.)', { [int]"$_" + 1 }

0.12.0


'0.11.11.0' -replace '(?<=\.)\d+(?=\.)', { [int]"$_" + 1 }

0.12.12.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...