Если бы вы спросили меня: «Что такое Ruby?» не более пяти месяцев назад я бы ответил «жемчужина». Что еще так точно. Я начал учиться кодировать на Ruby пять месяцев назад, и, хотя мне еще многое предстоит узнать, я стал чувствовать себя очень комфортно на этом удивительно дружественном языке. Одним из моих первых «больших» сольных проектов на Ruby была разработка простого CLI (интерфейса командной строки), который извлекал бы некоторые данные и представлял их пользователю.

Я начал с использования другого драгоценного камня Ruby, Bundler, для создания базовой основы для моего CLI. Чего я не понимал в то время, так это того, как много этот драгоценный камень может сделать для меня с точки зрения правильной настройки CLI. Что я действительно сделал, так это принял как должное проделанную работу. Чтобы избавить вас от запуска кода, не зная, что происходит, я проведу вас через создание каркаса CLI вручную. Тогда я покажу вам магию Bundler.

Во-первых, мы хотим настроить наш локальный каталог. В вашем терминале cd, пока вы не окажетесь в родительском каталоге, в котором вы хотите, чтобы ваш CLI жил. Для меня это выглядит примерно так:

mac-user@mac ~ % cd Development
mac-user@mac Development % 

Я не могу не подчеркнуть важность освоения команд оболочки. Чем меньше вам нужно использовать мышь, тем быстрее и увереннее вы будете строить строительные леса в будущем. Некоторые из них я использую каждый раз, когда пишу код:

cd <directory_path> #changes into the supplied working directory
ls #lists out all subdirectories within your working directory
ls -a #will also print out hidden folders
touch <file_path> #creates a file at the supplied path
mkdir <directory_path> #creates a folder at the supplied path
mkdir -p <directory_path> #will also create all parent folders

Теперь, когда мы находимся в правильном рабочем каталоге, начните с создания каталога CLI и открытия его в выбранном вами редакторе кода (я использую VSCode).

mac-user@mac Development % mkdir cli-example
mac-user@mac Development % code cli-example

Предполагая, что вы настроили команду оболочки VSCode code, VSCode откроет новое окно и cd перенесет вас в этот рабочий каталог. Теперь самое интересное! Леса! Я подробно опишу, для чего предназначена каждая секция в работающем геме CLI. С этого момента мы будем в этом рабочем каталоге:

mac-user@mac cli-example %

И поэтому я пропущу его из остальных окон кода для чистоты. Теперь к командам оболочки!

mkdir bin #will hold your run files
touch bin/run #will run the actual CLI
mkdir -p lib/cli-example #will hold your source code
touch lib/environment.rb #will build your CLI environment
touch lib/cli-example/cli.rb #will build your actual CLI itself
mkdir spec #will hold your test files
touch .gitignore #specify any ignored files for version control
touch Gemfile #specify any gem dependencies

Это должно помочь нам начать! К настоящему времени у вас должна быть файловая структура, которая выглядит примерно так:

cli-example
   - bin
      - run #this file needs no extension
   - lib
      - cli-example
         - cli.rb
      - environment.rb
   - spec
   - .gitignore
   - Gemfile

Теперь, когда в нашей файловой структуре есть некоторые кости, давайте начнем работать с нашим CLI! Для целей этого пошагового руководства я собираюсь вывести некоторый основной текст. Идея состоит в том, что, как только вы поймете, как все работает, вы сможете на этом основываться. Все это говорит о том, что прежде чем мы приступим к реальному кодированию, давайте настроим контроль версий и Git. Предполагая, что вы настроили Git (и службу фиксации по вашему выбору — я буду использовать GitHub), продолжайте и выполните следующие команды:

git init #initializes the local repository
git add . #adds all created files to be commited
git commit -m 'first commit' #commits those files
git remote add origin <git path here...> #sets up remote repository
git branch -M master #sets the master branch
git push -u origin master #pushes committed files to remote repo

Откройте файл bin/run. Это файл, который мы будем выполнять в нашем терминале. В идеале я должен иметь возможность ввести bin/run в свой терминал, и он должен запустить CLI. Давайте начнем. В наш файл bin/run вставьте следующий код.

#!/usr/bin/env ruby
require_relative '../lib/environment.rb'
CLI.new.call

Разберем каждую строку кода.

#!/usr/bin/env ruby

Это говорит нашей оболочке (нашему терминалу) интерпретировать оставшуюся часть кода в этом файле как Ruby. Без этого терминал не знал бы, что такое остальная часть кода, потому что нет команды Zsh (или Bash) require_relative или CLI.new.call. Точно так же, если вы хотите напрямую запустить код Ruby в своем терминале, вам нужно будет предварить его ruby.

require_relative '../lib/environment.rb'

Для этого требуется или загружается наш файл среды, расположенный по относительному пути '../lib/environment.rb'. Но зачем нам это нужно? Там даже ничего нет! Пока что. По мере роста нашего CLI мы, естественно, будем добавлять все больше и больше файлов. Мы поместим эти файлы в наш файл environment.rb, чтобы при загрузке нашей среды загружались и все остальные наши исходные файлы.

CLI.new.call

Технически это абсолютно ничего не дает прямо сейчас. Это еще не определено нами! Но это будет скоро — ведь именно здесь начнется наш CLI! Мы говорим нашему терминалу создать new экземпляр CLI, а затем запустить call на этом экземпляре. Все вместе эти три строчки кода запустят наш CLI в терминале. Отсюда давайте перейдем к нашему файлу cli.rb и создадим наш CLI.

class CLI
   def call
      puts "Hello World!"
   end
end

Мы делаем несколько вещей здесь. Во-первых, мы определяем класс CLI. Оттуда мы даем этому классу метод экземпляра call. Прямо сейчас все, что делает этот метод, — это puts "Hello World!" для терминала, но, добавляя методы экземпляра и условия, вы можете построить целую структуру меню для вашего CLI. Давайте хотя бы посмотрим, сможем ли мы получить «Hello World!» распечатать на наш терминал. Идите вперед и введите bin/run в свой терминал.

zsh: permission denied: bin/run

О, о! Наша оболочка по умолчанию не позволит вам запускать файлы. Это безопасность. Скажем нашей оболочке, что мы наверняка можем выполнить этот файл с помощью следующей команды:

chmod +x bin/run

chmod позволяет вам изменять/модифицировать разрешения для указанного каталога. +x говорит добавить (+) права на исполняемый файл (x) в bin/run (наш указанный каталог).

Теперь давайте введем bin/run.

Hello World!

Вуаля! У нас есть рабочая структура. Отсюда мы можем создавать методы и добавлять зависимости в наш CLI, чтобы сделать его своим. Вот пример из CLI, который я создал, чтобы очищать различные веб-сайты и предоставлять эту информацию пользователю. Это начало метода меню, и он использует другие методы, которые я определил в своем классе CLI.

def menu
   input = nil
   while input != 'exit'
      pros
      input = gets.chomp.downcase
      case input.to_s
         when '1'
            list_dps
         when '2'
            list_concord
         when '3'
            # and on and on...

Я надеюсь, что это дало некоторое представление о построении простой структуры CLI в Ruby. И пока я не забыл, вот как создать структуру CLI с помощью Bundler, что намного быстрее, но делает всю работу за вас и может привести к тому, что вы немного раздуетесь, если вы не собираетесь использовать все.

bundle new cli-example

Это создаст всю базовую структуру в вашем рабочем каталоге. Попробуйте, и вы поймете, что я имею в виду. Генераторы — это и благословение, и проклятие. Не полагайтесь на них во всем, но цените то, что они делают.