Всем привет! Одним из моих любимых языков является Go, в результате чего я задумался о написании чего-то вроде Package Manager… Ну или хотя бы поисковика пакетов. Есть идея, пора бы сесть за разработку. Конечно же в первую очередь я подумал о Go как о инструменте для решения проблемы. Но, немного поразмыслив, решил дать шанс манящему меня PowerShell, за изучение которого я садился уже раза 3, но что-то меня постоянно останавливало (скорее всего лень и отсутствие проектов, которые можно было бы на нем реализовать). Что же, сказано – сделано. Данная статья рассчитана на людей, не знакомых с PowerShell, но имеющих опыт в программировании. Если вам стало интересно, то добро пожаловать под кат.
Для начала было бы неплохо узнать, что такое PS. Википедия говорит следующее:
Теперь можно приступать к делу. Первая проблема, с которой столкнутся новички – это запрет на исполнение сторонних скриптов. Ребята из Microsoft пекутся о нашей с Вами безопасности, но мы же понимаем, что делаем ;). Так давайте исправим эту досадную заботу. Откройте окно PowerShell, которое выглядит примерно так:
И выполните следующую команду:
Set-ExecutionPolicy RemoteSigned
Система спросит у вас, осознаете ли Вы то, что делаете, отвечаем утвердительное Y.
Вообще основой PowerShell являются командлеты. Они имеют следующий синтаксис:
<Глагол>-<Существительное>
Это довольно удобно, так как вводит понимание того, что должно произойти. Помимо командлетов имеются так же Alias’ы для большинства стандартных команд, причет не только CMD, но и Bash. Например, Вы хотите очистить экран. Стандартный командлет для этого Clear-Host, но также можно воспользоваться алиасами для него: cls и clear. Со списком алиасов можно ознакомиться командой Get-Alias.
И так, мы произвели базовую настройку PowerShell и пришло время для написания скриптов. Расширением скриптов PowerShell является “*.ps1”. Создадим файл для разработки наших командлетов командой:
New-Item -Path 'C:workgoPS.ps1' -Type File -Force
Если с параметром -Path все понятно, то с остальными придется разобраться. -Type указывает тип создаваемого файла, так как нам нужен файл, мы явно указываем это. -Force же создает пути, если они не существуют.
Вопросом: откуда брать список модулей для Go? Ответ: нам в этом поможет ресурс Go-Search, который предоставляет очень удобное, а главное бесплатное API. Спасибо им за это.
Можно переходить в любимый редактор кода, но лично я могу посоветовать Вам использовать PowerShell ISE, любезно предустановленный в систему. Нужно создать каркас нашего модуля:
function Find-GoPackage {
}
Это наш будущий командлет. PS вещь не простая, в отличии от Bash и CMD оперирует объектами, а не строками, что очень удобно при работе с конвейером. Каркас есть, теперь займемся параметрами. Переменные в PS задаются аналогично PHP с помощью $my_var. При этом они могут быть как нетипизированные, так и типизированные.
# Нетипизированная
$no_type
# Типизированная, строка
[string]$have_type
Объявим блок аргументов:
[CmdletBinding()]
Param (
[string]$Name = ""
)
Как видно, задать аргументы проще простого, да и еще значение по умолчанию есть.
Сама логика работы следующая. В первую очередь нам необходимо произвести запрос на сервер. Сделать это можно несколькими способами, но, как по мне, самый простой это использовать Invoke-WebRequest, который вернет нам объект с содержимым ответа.
Введем переменную:
$uri = "http://go-search.org/api?action=search&q=" + $Name
PowerShell поддерживает работу с конвейером. Ответ от сервера приходит в виде json, но спасибо добрым людям, которые уже подумали о нас. В PS есть стандартные сериализаторы и десериализаторы объектов. ConvertFrom-Json принимает в себя строку Json и возвращает “сырой” объект с полями нашего json. Хватит слов, больше кода, а кода будет мало.
$hits = $($(Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json).hits
Мы передаем нашу ссылку в инвокер, берем из него содержимое ответа из поля .Content и передаем по конвейеру (конвейер это “|”) в ConvertFrom-JSON. Нас же, в свою очередь, интересует поле .hits, которое содержит список найденных модулей. Всего одна строчка выполнила всю работу за нас!
Осталось только вернуть наш список, ну это уже совсем просто:
return $hits
Привожу полный листинг:
function Find-GoPackage {
[CmdletBinding()]
Param (
[string]$Name = ""
)
$uri = "http://go-search.org/api?action=search&q=" + $Name
$hits = $($(Invoke-WebRequest -Uri $uri).Content | ConvertFrom-Json).hits
return $hits
}
Теперь снова перейдем в PowerShell и импортируем наш модуль в сеанс:
PS C: >. “C:workgoPS.ps1”
PowerShell проанализировал наш скрипт и готов к работе.
Выполните, например, команду “Find-GoPackage -Name json” и получите список найденных модулей для работы с json, ну а для красоты можно еще и форматирование добавить:
Find-GoPackage json | Format-Table -Wrap -AutoSize
Имеем на выходе аккуратную табличку.
Правда импортировать каждый раз модуль не удобно, поэтому можно сделать одну интересную вещь: в PS есть система профилей. Профиль – это файл, который исполняется каждый раз, когда вы открываете терминал.
Введите в PS следующее:
Test-Path $PROFILE
$PROFILE это переменная среды, содержащая путь до вашего файла профиля. Если команда выше вернула $false, значит ваш профиль не настроен. В таком случае выполните следующую команду:
New-Item -Path $PROFILE -Type File -Force
Откройте этот файл:
notepad $PROFILE
И скопируйте наш вышенаписанный код в файл, сохраните, перезапустите PowerShell и проверьте, что все работает.
На этом все, спасибо за внимание!
Автор: pavelgeme2