Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Go

Let's Go: программы командной строки с Golang

by
Read Time:7 minsLanguages:

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

Обзор

Язык Go - это захватывающий новый язык, который набирает большую популярность по уважительной причине. В этом уроке вы узнаете, как писать программы для командной строки с помощью Go. Пример программы называется multi-git, и она позволяет вам выполнять команды git одновременно в нескольких репозиториях.

Краткое введение в Go

Go - это C-подобный язык с открытым исходным кодом, созданный в Google некоторыми из первоначальных хакеров C и Unix, которые были мотивированы своей неприязнью к C ++. Это отображено в дизайне Go, который сделал несколько неортодоксальных выборов, таких как отказ от наследования реализации, шаблонов и исключений. Go прост, надежен и эффективен. Его наиболее отличительной особенностью является явная поддержка параллельного программирования через так называемые goroutines и каналы.

Прежде чем приступить к анализу примера программы, следуйте официальному руководству, чтобы подготовиться к разработке на Go.

Программа Multi-Git

Программа multi-git - это простая, но полезная программа Go. Если вы работаете в команде, в которой кодовая база разбита по нескольким git-репозиториям, вам часто приходится вносить изменения в несколько репозиториев. Это проблема, потому что у git нет концепции нескольких репозиториев. Все вращается вокруг одного хранилища.

Это становится особенно проблематичным, если вы используете ветки. Если вы работаете с функцией, которая касается трех репозиториев, вам нужно будет создать ветку в каждом из этих репозиториев, а затем не забывать проверять, извлекать, толкать и объединять их все одновременно. Это не тривиально. Multi-git управляет набором репозиториев и позволяет вам работать со всем набором одновременно. Обратите внимание, что текущая версия multi-git требует, чтобы вы создавали ветви по отдельности, но я могу добавить эту функцию позже.

Изучив способ реализации multi-git, вы многое узнаете о написании программ для командной строки на Go.

Пакеты и импорт

Программы Go организованы в пакеты. Программа multi-git состоит из одного файла с именем main.go. В верхней части файла указано имя пакета 'main', а затем список импорта. Импортируются другие пакеты, используемые multi-git.

Например, пакет fmt используется для форматированного ввода-вывода, подобного printf и scanf в C. Go поддерживает установку пакетов из различных источников с помощью команды go get. Когда вы устанавливаете пакеты, они попадают в пространство имен в переменной среды $GOPATH. Вы можете устанавливать пакеты из различных источников, таких как GitHub, Bitbucket, код Google, Launchpad и даже сервисы IBM DevOps, используя несколько распространенных форматов контроля версий, таких как git, subversion, mercurial и bazaar.

Аргументы командной строки

Аргументы командной строки являются одной из наиболее распространенных форм предоставления ввода программам. Они просты в использовании, позволяют запускать и настраивать программу в одну строку и имеют отличную поддержку синтаксического анализа на многих языках. Go называет их «флагами» командной строки и имеет пакет flag для указания и анализа аргументов командной строки (или флагов).

Как правило, вы анализируете аргументы командной строки в начале вашей программы, и multi-git следует этому соглашению. Точкой входа является функция main(). Первые две строки определяют два флага, называемые «command» и «ignoreErrors». Каждый флаг имеет имя, тип данных, значение по умолчанию и строку справки. Вызов flag.Parse() проанализирует фактическую командную строку, переданную программе, и заполнит определенные флаги.

Также возможно получить доступ к неопределенным аргументам через функцию flag.Args(). Таким образом, флаги обозначают предопределенные аргументы, а «аргументы» - необработанные аргументы. Необработанные аргументы индексируются на основе 0.

Переменные среды

Другая распространенная форма конфигурации программы - переменные среды. Когда вы используете переменные среды, вы можете запускать одну и ту же программу несколько раз в одной и той же среде, и во всех запусках будут использоваться одни и те же переменные среды.

Multi-git использует две переменные среды: "MG_ROOT" и "MG_REPOS". Multi-git предназначен для управления группой репозиториев git, имеющих общий родительский каталог. Это "MG_ROOT". Имена хранилища указываются в MG_REPOS в виде строки, разделенной запятыми. Чтобы прочитать значение переменной окружения, вы можете использовать функцию os.Getenv().

Проверка списка репозитория

Теперь, когда он нашел корневой каталог и имена всех репозиториев, multi-git проверяет, что каждый репозиторий существует под root и что это действительно git-репозиторий. Проверка так же проста, как поиск подкаталога .git для каждого каталога репозитория.

Сначала определяется массив строк с именем «repos». Затем он перебирает все имена репо и создает путь к репозиторию путем объединения корневого каталога и имени репо. Если вызов [os.Stat()]() завершается неудачно для подкаталога .git, он регистрирует ошибку и завершает работу. В противном случае путь к хранилищу добавляется к массиву репозитория.

Go имеет уникальную возможность обработки ошибок, где функции часто возвращают как возвращаемое значение, так и объект ошибки. Посмотрите, как os.Stat() возвращает два значения. В этом случае заполнитель "_" используется для хранения фактического результата, потому что вы заботитесь только об ошибке. Go очень строг и требует использования именованных переменных. Если вы не планируете использовать значение, вам следует присвоить его «_», чтобы избежать ошибки компиляции.

Выполнение команд оболочки

На данный момент у вас есть список путей к хранилищам, где мы хотим выполнить команду git. Как вы помните, мы получили командную строку git в виде одного аргумента командной строки (флага), называемого «command». Его нужно разделить на массив компонентов (команда git, подкоманда и опции). Вся команда в виде строки также хранится для отображения.

Теперь все готово для перебора каждого репозитория и выполнения команды git в каждом из них. Снова используется циклическая конструкция for ... range. Во-первых, multi-git меняет свой рабочий каталог на текущий целевой репозиторий «r» и печатает команду git. Затем он выполняет команду с помощью функции exec.Command() и печатает комбинированный вывод (как стандартный вывод, так и стандартную ошибку).

Наконец, он проверяет, была ли ошибка во время выполнения. Если произошла ошибка и флаг ignoreErrors имеет значение false, то вылетает multi-git. Причиной необязательного игнорирования ошибок является то, что иногда все в порядке, если команды не выполняются в некоторых репозиториях. Например, если вы хотите проверить ветку «Cool Feature» во всех репозиториях, в которых есть эта ветвь, вам все равно, если проверка не удалась в репозиториях, у которых нет этой ветки.

Заключение

Go - простой, но мощный язык. Он предназначен для крупномасштабного системного программирования, но отлично работает и для небольших программ командной строки. Минимальный дизайн Go резко контрастирует с другими современными языками, такими как Scale и Rust, которые также очень мощные и хорошо продуманные, но имеют очень крутую кривую обучения. Я призываю вас попробовать Go и экспериментировать. Это очень весело.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.