Skip to content

Instantly share code, notes, and snippets.

@maestrow
Last active March 24, 2018 04:36
Show Gist options
  • Save maestrow/94d99017380adbcadff29f048f423729 to your computer and use it in GitHub Desktop.
Save maestrow/94d99017380adbcadff29f048f423729 to your computer and use it in GitHub Desktop.
Start Scripting with F# and Paket on Windows (Использование Paket в скриптах F# на Windows, автоматизация)

Эффективное использование менеджера пакетов Paket в скриптах и проектах на F#

В статье описывается способ автоматизации получения менеджера пакетов. Отмечены действия для использования внешних пакетов в вашем F#-скрипте. Рассматривается опция storage: none. Для автоматизации используется PowerShell.

Автоматизация получения Paket

Получение Paket

Для того, чтобы использовать Paket, предполагается следующая последовательность действий:

  • Создать в директории проекта поддиректорию .paket
  • Скачать загрузчик paket.bootstrapper.exe в директорию .paket
  • Запустить paket.bootstrapper.exe, загрузчик скачает последнюю версию менеджера пакетов paket.exe

Это все. Далее возможно выполнение команд менеджера пакетов .paket/paket.exe

Несмотря на то, что получить Paket просто, проделывать эти действия для каждого проекта или скрипта утомительно. И далее я предлагаю это автоматизировать.

Автоматизация

Для автоматизации получения Paket напишем PowerShell-функцию, которая будет создавать в папке проекта поддиректорию .paket и закачивать в нее paket.bootstrapper.exe под именем paket.exe (это т.н. режим Magic mode). А также добавим в переменную PATH путь до поддиректории .paket, чтобы обращаться к менеджеру пакетов прямо из директории проекта. Описанные задачи уже реализованы в скрипте paket-env.ps1.

Чтобы воспользоваться скриптом автоматизации:

  • Скачайте скрипт paket-env.ps1 и поместите его в директории вашего PowerShell-профиля (имя этой директории можно узнать выполнив Split-Path $profile).
  • Отредактируйте скрипт вашего PowerShell-профиля, импортировав в него скрипт автоматизации paket-env.ps1. Для редактирования скрипта профиля выполните ise $profile (подробнее про редактирование профиля powershell см. здесь). Добавьте в профиль строчки:
$scriptDir = Split-Path $MyInvocation.MyCommand.Path
import-module "$scriptDir\paket-env.ps1"

Сохраните.

Теперь для инициализации менеджера пакетов Paket достаточно будет выполнить команду paket-bootstrap (из оболочки Powershell, в директории вашего проекта). И далее обращение к paket.exe будет доступно прямо из директории проекта:

  • paket-bootstrap - наша функция.
  • paket init - создает пустой файл paket.dependencies

Опция storage: none

С опцией storage: none (указывается в файле paket.dependencies) для сохранения пакетов Paket будет использовать общий кеш и не будет создавать в проекте отдельную папку packages, что позволяет экономить дисковое пространство и оставляет директорию проекта более чистой. Размер папки packages может быть 300Мб-400Мб, а это совсем не нужно для тестовых проектов и папок с F#-скриптами. Особенно это актуально на ноутбуках с небольшими по объему SSD.

Если в paket.dependencies используются группы, то опцию storage: none нужно указывать для каждой группы.

Использование внешних пакетов в скриптах на F#

Скрипты на F# - удобный инструмент для экспериментов, для быстрого написания и проверки небольших решений (функций, модулей), из которых в дальнейшем может складываться целый проект.

Для того, чтобы из скрипта сослаться на внешную библиотеку (nuget-библиотеку или модуль с github или модуль, взятый из произвольного URL), воспользутесь инструкцией ниже:

Добавление пакетов в проект

Для добавления пакета используется команда paket add. Например, paket add Fue. Добавленные пакеты будут регистрироваться в файле paket.dependencies.

Генерация include-скриптов (скриптов для подключения пакетов)

После того как вы добавите в проект нужные пакеты, необходимо сгенерировать скрипт(ы) для подключения пакетов: paket generate-load-scripts (подробнее здесь). Include-скрипты будут сгенерированы в папке .paket\load. Можно ограничиться скриптами только для определенной платформы, например paket generate-load-scripts --framework netstandard2.0. Также можно добавить опцию generate_load_scripts: true в paket.dependencies и тогда include-скрипты будут генерироваться при установке пакетов, т.е. при выполнении paket install.

Добавление ссылок на пакеты в ваш скрипт

После того как пакеты добавлены в проект и сгенерированы include-скрипты, на пакеты можно добавлять ссылки в ваш собственный скрипт, например #load @".paket\load\netstandard2.0\Fue.fsx".

To initialize Paket for your F# project use

Manual way:

  • Create .paket subdir in your project folder
  • Download paket.bootstrapper.exe to .paket
  • run .paket/paket.bootstrapper.exe
  • run .paket/paket init

OR automated way:

You can include paket-env.ps1 in your profile script and then to bootstrap paket just run: paket-bootstrap; paket init

# Automate your everyday paket bootstrapping.
# installation: Add this script in your `$profile` script by `import-module "$PSScriptRoot\Paket-Bootstrap.ps1"`.
# usage: enter your project dir and call `Paket-Bootstrap` to download fresh version, and then refer the paket directly, i.e. `paket init` (not ./paket/paket.exe init).
$env:Path += ";./.paket"
function Paket-Bootstrap {
mkdir -Force .paket
$html = Invoke-WebRequest -Uri "https://github.com/fsprojects/Paket/releases/latest"
$href = $html.ParsedHtml.getElementsByTagName("a") | where { $_.href -Like "*paket.bootstrapper.exe" } | select -ExpandProperty href | select -Unique
$url = $href -replace "about:/", "https://github.com/"
(New-Object System.Net.WebClient).DownloadFile($url, "$pwd/.paket/paket.exe")
}

Using Paket with F# script (*.fsx) cheat sheet

  1. Init Paket
paket-bootstrap
paket init
  1. Add storage: none to paket.dependencies: PS> "storage: none" | Add-Content "paket.dependencies"
  2. Add packages: paket add <package ID>
  3. paket generate-load-scripts or paket generate-load-scripts --framework <framework>
  4. Use packages like this: #load @".paket\load\<framework>\<package ID>.fsx"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment