Рейк 101
() translation by (you can also view the original English article)
В этой статье объясняются основы Rake. Это супер популярный инструмент сборки, написанный на Ruby. Он предлагает большую гибкость и используется для управления всеми видами задач. Если вы используете Rails, я рекомендую взглянуть под капотом, чтобы узнать, какие задачи имеются в вашем распоряжении, и как писать свои собственные.
Темы
- Что такое Rake?
- Список заданий
- Начинаем работу
- Пространства имен
- Предпосылки
- Передача аргументов
- Задачи, представляющие интерес
Что такое Rake?
Благодаря Rails, Rake стал стандартом де-факто как инструмент для сборки Ruby приложений. Он очень популярен в сообществе Ruby. Очень рано команда Rails решила использовать Rake в качестве сборщика для Rails, что означало, что в прошлом, когда вы загружали Rails, вам также нужна была копия Rake. Таким образом Rake был представлен сразу куче людей. Чуть позже он был включен в Ruby (1.9).
Rake де-факто заменил Unix-утилиту Make как инструмент сборки на территории Ruby. Инструмент построения, такой как Rake, удобен для автоматизации различных задач - программного обеспечения. Он часто используется для задач администрирования в Rails - вот где вы, скорее всего, уже успели столкнуться с ним, но однако вариантов его использования достаточно много. Некоторые люди пишут свои книги в Markdown и настраивают задачи Rake, которые преобразуют соответствующие файлы в промежуточные HTML-файлы, которые затем, в свою очередь, преобразуются в форматы электронных книг. Но остается еще много проблем, чтобы использовать Rake для этого.
Что делает Rake очень сильным, так это то, что эти задачи могут быть связаны друг с другом и могут быть построены друг на друге. Кроме того, поскольку он написан в Ruby, вы можете написать любой код Ruby для своих задач. Хотите использовать библиотеки Ruby в своих задачах Rake? Нет проблем! Интересный факт: это самый загруженный RubyGem с более чем 100 миллионами загрузок. Так что это определенно то, что должно быть в вашем наборе для инструментов, и на что вы должны обратить больше внимания.
Он был придуман покойным Джимом Вейрихом, известным и любимым разработчиком, докладчиком и вкладчиком в экосистему Ruby. Это прекрасный инструмент, действительно, спасибо, Джим! ПОКОЙСЯ С МИРОМ!
Список заданий
Давайте рассмотрим некоторые задачи, которые Rails предлагает прямо из коробки. Бьюсь об заклад, вы немного удивлены тем, что вам доступно. В соответствующем каталоге вашего приложения или вашего Rakefile вы можете перечислить их, введя в оболочку следующее:
1 |
rake --tasks |
2 |
|
3 |
#or |
4 |
|
5 |
rake -T |
Вывод:
1 |
rake about # List versions of all Rails frameworks and the environment |
2 |
rake assets:clean[keep] # Remove old compiled assets |
3 |
rake assets:clobber # Remove compiled assets |
4 |
rake assets:environment # Load asset compile environment |
5 |
rake assets:precompile # Compile all the assets named in config.assets.precompile |
6 |
rake cache_digests:dependencies # Lookup first-level dependencies for TEMPLATE (like messages/show or comm... |
7 |
rake cache_digests:nested_dependencies # Lookup nested dependencies for TEMPLATE (like messages/show or comments/... |
8 |
rake db:create # Creates the database from DATABASE_URL or config/database.yml for the cu... |
9 |
rake db:drop # Drops the database from DATABASE_URL or config/database.yml for the curr... |
10 |
rake db:fixtures:load # Load fixtures into the current environment's database |
11 |
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog) |
12 |
rake db:migrate:status # Display status of migrations |
13 |
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n) |
14 |
rake db:schema:cache:clear # Clear a db/schema_cache.dump file |
15 |
rake db:schema:cache:dump # Create a db/schema_cache.dump file |
16 |
rake db:schema:dump # Create a db/schema.rb file that is portable against any DB supported by AR |
17 |
rake db:schema:load # Load a schema.rb file into the database |
18 |
rake db:seed # Load the seed data from db/seeds.rb |
19 |
rake db:setup # Create the database, load the schema, and initialize with the seed data ... |
20 |
rake db:structure:dump # Dump the database structure to db/structure.sql |
21 |
rake db:structure:load # Recreate the databases from the structure.sql file |
22 |
rake db:version # Retrieves the current schema version number |
23 |
rake doc:app # Generate docs for the app -- also available doc:rails, doc:guides (optio... |
24 |
rake log:clear # Truncates all *.log files in log/ to zero bytes (specify which logs with... |
25 |
rake middleware # Prints out your Rack middleware stack |
26 |
rake notes # Enumerate all annotations (use notes:optimize, :fixme, :todo for focus) |
27 |
rake notes:custom # Enumerate a custom annotation, specify with ANNOTATION=CUSTOM |
28 |
rake rails:template # Applies the template supplied by LOCATION=(/path/to/template) or URL |
29 |
rake rails:update # Update configs and some other initially generated files (or use just upd... |
30 |
rake routes # Print out all defined routes in match order, with names |
31 |
rake secret # Generate a cryptographically secure secret key (this is typically used t... |
32 |
rake spec # Run all specs in spec directory (excluding plugin specs) |
33 |
rake spec:controllers # Run the code examples in spec/controllers |
34 |
rake spec:features # Run the code examples in spec/features |
35 |
rake spec:helpers # Run the code examples in spec/helpers |
36 |
rake spec:models # Run the code examples in spec/models |
37 |
rake spec:views # Run the code examples in spec/views |
38 |
rake stats # Report code statistics (KLOCs, etc) from the application or engine |
39 |
rake time:zones:all # Displays all time zones, also available: time:zones:us, time:zones:local... |
40 |
rake tmp:clear # Clear session, cache, and socket files from tmp/ (narrow w/ tmp:sessions... |
41 |
rake tmp:create # Creates tmp directories for sessions, cache, sockets, and pids |
Вывод в приложении Rails на удивление многочисленный, не так ли? Вы можете найти гораздо более удобные задачи, чем обычные rake db:migrate
или rake routes
, с которыми мы так хорошо знакомы и выполняем по несколько раз на ежедневной основе.
Слева вы видите различные задачи, а справа вы видите, что дополнительно предоставляется как описание для каждой задачи. Если вы хотите увидеть полный список, который помимо прочего включает также задачи, которым не хватает описания, вам нужно добавить дополнительный флаг.
Shell:
1 |
rake -T -A |
2 |
|
3 |
#or |
4 |
|
5 |
rake -T -all |
Вывод:
1 |
rake about # List versions of all Rails frameworks and the environment |
2 |
rake assets:clean[keep] # Remove old compiled assets |
3 |
rake assets:clobber # Remove compiled assets |
4 |
rake assets:environment # Load asset compile environment |
5 |
rake assets:precompile # Compile all the assets named in config.assets.precompile |
6 |
rake cache_digests:dependencies # Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html) |
7 |
rake cache_digests:nested_dependencies # Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html) |
8 |
rake db:_dump # |
9 |
rake db:abort_if_pending_migrations # |
10 |
rake db:charset # |
11 |
rake db:collation # |
12 |
rake db:create # Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config) |
13 |
rake db:create:all # |
14 |
rake db:drop # Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config) |
15 |
rake db:drop:all # |
16 |
rake db:fixtures:identify # |
17 |
rake db:fixtures:load # Load fixtures into the current environment's database |
18 |
rake db:forward # |
19 |
rake db:load_config # |
20 |
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog) |
21 |
rake db:migrate:down # |
22 |
rake db:migrate:redo # |
23 |
rake db:migrate:reset # |
24 |
rake db:migrate:status # Display status of migrations |
25 |
rake db:migrate:up # |
26 |
rake db:purge # |
27 |
rake db:purge:all # |
28 |
rake db:reset # |
29 |
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n) |
30 |
rake db:schema:cache:clear # Clear a db/schema_cache.dump file |
31 |
rake db:schema:cache:dump # Create a db/schema_cache.dump file |
32 |
rake db:schema:dump # Create a db/schema.rb file that is portable against any DB supported by AR |
33 |
rake db:schema:load # Load a schema.rb file into the database |
34 |
rake db:schema:load_if_ruby # |
35 |
rake db:seed # Load the seed data from db/seeds.rb |
36 |
rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first) |
37 |
rake db:structure:dump # Dump the database structure to db/structure.sql |
38 |
rake db:structure:load # Recreate the databases from the structure.sql file |
39 |
rake db:structure:load_if_sql # |
40 |
rake db:test:clone # |
41 |
rake db:test:clone_schema # |
42 |
rake db:test:clone_structure # |
43 |
rake db:test:deprecated # |
44 |
rake db:test:load # |
45 |
rake db:test:load_schema # |
46 |
rake db:test:load_structure # |
47 |
rake db:test:prepare # |
48 |
rake db:test:purge # |
49 |
rake db:version # Retrieves the current schema version number |
50 |
rake default # |
51 |
rake doc # |
52 |
rake doc/app # |
53 |
rake doc/app/created.rid # |
54 |
rake doc:app # Generate docs for the app -- also available doc:rails, doc:guides (options: TEMPLATE=/rdoc-template.rb, TITLE="Custom Title") |
55 |
rake doc:clobber # |
56 |
rake doc:clobber_app # |
57 |
rake doc:clobber_rails # |
58 |
rake doc:guides # |
59 |
rake doc:rails # |
60 |
rake doc:reapp # |
61 |
rake doc:rerails # |
62 |
rake environment # |
63 |
rake html # |
64 |
rake html/created.rid # |
65 |
rake log:clear # Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development) |
66 |
rake magic # Magic rake task |
67 |
rake middleware # Prints out your Rack middleware stack |
68 |
rake no_description # |
69 |
rake notes # Enumerate all annotations (use notes:optimize, :fixme, :todo for focus) |
70 |
rake notes:custom # Enumerate a custom annotation, specify with ANNOTATION=CUSTOM |
71 |
rake notes:fixme # |
72 |
rake notes:optimize # |
73 |
rake notes:todo # |
74 |
rake rails:template # Applies the template supplied by LOCATION=(/path/to/template) or URL |
75 |
rake rails:templates:copy # |
76 |
rake rails:update # Update configs and some other initially generated files (or use just update:configs or update:bin) |
77 |
rake rails:update:bin # |
78 |
rake rails:update:configs # |
79 |
rake railties:install:migrations # |
80 |
rake routes # Print out all defined routes in match order, with names |
81 |
rake secret # Generate a cryptographically secure secret key (this is typically used to generate a secret for cookie sessions) |
82 |
rake spec # Run all specs in spec directory (excluding plugin specs) |
83 |
rake spec:controllers # Run the code examples in spec/controllers |
84 |
rake spec:features # Run the code examples in spec/features |
85 |
rake spec:helpers # Run the code examples in spec/helpers |
86 |
rake spec:models # Run the code examples in spec/models |
87 |
rake spec:prepare # |
88 |
rake spec:statsetup # |
89 |
rake spec:views # Run the code examples in spec/views |
90 |
rake stats # Report code statistics (KLOCs, etc) from the application or engine |
91 |
rake time:zones:all # Displays all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6 |
92 |
rake time:zones:local # |
93 |
rake time:zones:us # |
94 |
rake tmp # |
95 |
rake tmp/cache # |
96 |
rake tmp/cache/assets # |
97 |
rake tmp/cache/assets/development # |
98 |
rake tmp/cache/assets/production # |
99 |
rake tmp/cache/assets/test # |
100 |
rake tmp/pids # |
101 |
rake tmp/sessions # |
102 |
rake tmp/sockets # |
103 |
rake tmp:cache:clear # |
104 |
rake tmp:clear # Clear session, cache, and socket files from tmp/ (narrow w/ tmp:sessions:clear, tmp:cache:clear, tmp:sockets:clear) |
105 |
rake tmp:create # Creates tmp directories for sessions, cache, sockets, and pids |
106 |
rake tmp:pids:clear # |
107 |
rake tmp:sessions:clear # |
108 |
rake tmp:sockets:clear # |
Удивительно, почти в три раза больше! Взгляните на них и поиграйте с ними, если хотите, но зафиксируйте основные моменты в памяти для последующего использования в будущем. Проверка задач, чтобы увидеть, какие вам доступны, может в будушем помешать вам повторно изобретать колесо.
Начинаем работу
Rakefile может иметь один из следующих пяти вариантов:
- rakefile.rb
- rakefile
- Rakefile
- Rakefile.rb
- .rake файлы
В основном вы увидите простую версию Rakefile
, но для такой структуры, как Rails, требуется более сложная организация. Используйте то, что вам больше по душе. Вы начинаете с создания Rakefile
или файлов с расширением .rake
, если вы хотите логически разбивать задачи на несколько файлов. Затем определите свои задачи внутри любого из них.
Организация пользовательских Rakefile
Rails делает это невероятно простым. Он содержит Rakefile в корне вашего приложения. В котором находится следующее:
Rakefile
1 |
require File.expand_path('../config/application', __FILE__) |
2 |
|
3 |
Rails.application.load_tasks |
Когда у вас много пользовательских задач, имеет смысл разделить их на дискретные файлы .rake
и поместить их в каталог lib/tasks
. Rakefile выше просто загружает их, но каталог lib
является лучшим логическим местом для задач. Существует даже генератор Rails для автоматизации части процесса. Если вы наберете:
Shell
1 |
rails generate some_task |
2 |
|
3 |
=> create lib/tasks/some_task.rake |
Вы получите Rakefile, который будет автоматически помещен в нужный каталог. Даже задание уже будет настроено для вас. Прелестно! В других проектах, не использующих Rails, вам просто нужно создать каталог rakelib
и поместить туда Rakefiles - желательно с расширениями .rake
. Затем создайте файл под названием Rakefile
, и все эти файлы уже в вашем распоряжении.
Анатомия заданий Rake
lib/tasks/some_task.rake
1 |
desc 'List versions of all Rails frameworks and the environment' |
2 |
task :about do |
3 |
puts 'Some magic goes in here…' |
4 |
end
|
Для всех новичков Ruby среди вас, а также для людей, живущих на тяжелых языках, так оно и будет выглядеть в круглых скобках.
1 |
desc('List versions of all Rails frameworks and the environment') |
2 |
task(:about) do |
3 |
puts('Some magic goes in here…') |
4 |
end
|
Выглядит кстати очень странно. Просто уберите лишние круглые скобки - никто не пишет задачи таким образом.
Мы представили именованную задачу :about
с описанием, которое не только напоминает нам в будущем то, что мы хотели достичь с определенными задачами, но также появляется, когда мы запускаем rake -T
. Не ленитесь на эту часть, оно того стоит.
Ниже приведена задача ключевого слова, определяющая новую задачу с именем about
. Это может быть вызвано в командной строке с помощью rake about
, затем происходит магия. rake :about
, с другой стороны, заставит Rake отменить задачу, не зная «как построить задачу: about».
В блоке do end
у нас есть lambda
, и ее тело определяет, что делает задача. Это базовая настройка, в которой потребуется задача. Конечно, это предлагает гораздо больше возможностей, но общая структура такая же.
require/import
Некий Rakefile
1 |
require './whatever.rb' |
Если вам нужно включить другие файлы Ruby или Rakefiles, это может быть легко достигнуто стандартным require
.
Некий Rakefile
1 |
import 'whatever.rb' |
Сам Rake предоставляет нам другой способ сделать это - метод import
. Его можно использовать в любой строке Rakefile. Это поможет, когда вы столкнетесь с проблемой, когда необходимый файл был загружен до того, как Rakefile закончил загрузку. С другой стороны импортируемый файл всегда будет загружаться после Rakefile.
invoke & execute
Иногда вам может потребоваться выполнить определенную задачу из класса Task
вручную. Для этого у вас есть два метода класса Rake::Task
: execute
и invoke
.
1 |
Rake::Task['some_task'].invoke |
2 |
Rake::Task['some_task'].execute |
С кодом Rake::Task['some_task']
мы выполнили задачу some_task
Rake. Он возвращает экземпляр класса Rake::Task
и затем запускает любой доступный ему метод.
Пространства имен
Очень крутой особенностью является способность разбивать ваши задачи по пространствам имен . Вероятно, вы уже давно это использовали. Когда вы запускаете rake db: migrate
, вы использовали, например, пространство имен db
. Вы вызываете задачу, разделив ее на двоеточие :
из пространства имен. Пространства имен - это удобный способ организовать ваши задачи внутри файла Rake - он логически разделяет их. Множественные пространства имен, такие как rake time:zones:all
тоже между прочим имеют место быть.
Другие примеры включают:
1 |
rake db:drop |
2 |
rake db:seed |
3 |
rake log:clear |
4 |
rake spec:views |
5 |
rake spec:models |
6 |
rake db:rollback |
7 |
rake spec:helpers |
8 |
rake spec:features |
9 |
rake db:schema:load |
10 |
rake assets:precompile |
11 |
rake db:migrate:status |
Некий Rakefile
1 |
namespace :db do |
2 |
desc 'Migrating some stuff' |
3 |
task :migrate do |
4 |
...
|
5 |
end
|
6 |
end
|
Это базовая настройка. На самом деле это намного сложнее и может быть многократно вложенным. Быстро загляните в кодовую базу Rails и убедитесь сами, как реализован rake db:migrate
. Не переживайте если там совсем ничего не понятно. Просто осмотритесь, попытайтесь понять, как он структурирован, и двигайтесь дальше.
Предпосылки
Другая стратегия для организации ваших задач и сохранения их согласно принципу DRY использует предварительные условия для выполнения задачи. Это похоже на зависимость, которая должна запускаться сначала до того, как фактическая задача начнет свою работу. Таким образом, вы можете создавать более сложные задачи - настолько сложные, насколько вам нужно. Но я бы порекомендовал не слишком умничать и держать свои задачи как можно проще - и так же легко понятными, насколько это вообще возможно.
Некий Rakefile
1 |
task :stop_megalomaniac do |
2 |
puts 'Lots of smart talk, car chases and guns fired' |
3 |
end
|
4 |
|
5 |
task :bond_saves_the_day => :stop_psychotic_megalomaniac do |
6 |
puts 'Lots of Dom Pérignon, oysters and bond girl business' |
7 |
end
|
Если вы хотите полагаться на несколько задач, вы просто привязываете их к массиву. Конечно, порядок, в котором вы их распологаете, имеет значение.
1 |
task :get_mr_wolf do |
2 |
puts "You ain’t got no problem Jules, I’m on it! Go in there and chill them out and wait for the wolf who should be coming directly!" |
3 |
end
|
4 |
|
5 |
task :figure_out_bonnie_situation do |
6 |
puts "If I was informed correctly, the clock is ticking. Is that right Jimmy?" |
7 |
end
|
8 |
|
9 |
task :calm_down_jimmy do |
10 |
puts "Jimmy, do me a favor, will you? I smelled some coffee back there. Would you make me a cup?" |
11 |
end
|
12 |
|
13 |
task :get_vince_vega_in_line do |
14 |
puts "Come again? Get it straight buster. I’m not here to say please! I’m here to tell you what to do!" |
15 |
end
|
16 |
|
17 |
task :clean_car do |
18 |
puts "I need you two fellas to take those cleaning products and clean the inside of the car. I’m talking fast, fast, fast!" |
19 |
end
|
20 |
|
21 |
task :clean_crew do |
22 |
puts "Jim, the soap! O.K. gentlemen, you both been to county before I’m sure. Here it comes!" |
23 |
end
|
24 |
|
25 |
task :get_rid_of_evidence_at_monster_joes do |
26 |
puts "So what’s with the outfits? You guys are going to a Volleyball game or something?" |
27 |
end
|
28 |
|
29 |
task :drive_into_the_sunrise do |
30 |
puts "Call me Winston!" |
31 |
end
|
32 |
|
33 |
task :solve_bonnie_situation => [:get_mr_wolf, :calm_down_jimmy, :figure_out_bonnie_situation, :get_vince_vega_in_line, :clean_car, :clean_crew, :get_rid_of_evidence_at_monster_joes, :drive_into_the_sunrise] do |
34 |
puts "You know, I’d go for breakfast. Feel like having breakfast with me?" |
35 |
end
|
Если вы выполняете задачу Rake, которая зависит от другой, мы получим следующий результат:
Shell
1 |
$ rake solve_bonnie_situation |
2 |
You ain’t got no problem Jules, I’m on it! Go in there and chill them out and wait for the wolf who should be coming directly! |
3 |
Jimmy, do me a favor, will you? I smelled some coffee back there. Would you make me a cup? |
4 |
If I was informed correctly, the clock is ticking. Is that right Jimmy? |
5 |
Come again? Get it straight buster. I’m not here to say please! I’m here to tell you what to do! |
6 |
I need you two fellas to take those cleaning products and clean the inside of the car. I’m talking fast, fast, fast! |
7 |
Jim, the soap! O.K. gentlemen, you both been to county before I’m sure. Here it comes! |
8 |
So what’s with the outfits? You guys are going to a Volleyball game or something? |
9 |
Call me Winston! |
10 |
You know, I’d go for breakfast. Feel like having breakfast with me? |
Порядок, в котором вы определяете свои Rake-задачи, не влияет на вывод - только порядок, в котором вы ставите необходимые задачи в массиве для зависимостей задачи. Кроме того, для этого используйте hashrocket синтаксис =>
.
Длинный список зависимостей может быть запахом кода. Если вам приходится иметь дело с чем-то долго, очистите его, инкапсулируя его внутри метода, который мы затем передаем как необходимое условие.
1 |
def mr_wolf_tasks |
2 |
[:get_mr_wolf, :calm_down_jimmy, :figure_out_bonnie_situation, :get_vince_vega_in_line, :clean_car, :clean_crew, :get_rid_of_evidence_at_monster_joes, :drive_into_the_sunrise] |
3 |
end
|
4 |
|
5 |
...
|
6 |
|
7 |
task :solve_bonnie_situation => mr_wolf_tasks do |
8 |
puts 'You know, I’d go for breakfast. Feel like having breakfast with me?' |
9 |
end
|
В контексте предпосылок следует иметь в виду, что вам нужно только указать пространство имен, если вы находитесь за пределами соответствующего.
Некий Rakefile
1 |
namespace :marsellus_wallace do |
2 |
task :call_winston_wolf do |
3 |
...
|
4 |
end
|
5 |
end
|
6 |
|
7 |
task :solve_bonnie_situation => 'marsellus_wallace:call_winston_wolf' do |
8 |
...
|
9 |
end
|
10 |
|
11 |
namespace :marsellus_wallace do |
12 |
task :call_winston_wolf do |
13 |
...
|
14 |
end
|
15 |
|
16 |
task :solve_bonnie_situation => :call_winston_wolf do |
17 |
...
|
18 |
end
|
19 |
end
|
Важно отметить, что: если вам нужно указать пространство имен, вам необходимо передать необходимое условие в виде строки => 'marsellus_wallace: call_winston_wolf'
.
Конечно, приведенные выше примеры - глупые, а не реальные примеры, но цель заключалась в том, чтобы показать вам, как работают предпосылки, и как вы можете объединить их, пока они зависят друг от друга.
Передача аргументов
У вас есть два варианта передачи аргументов для задач Rake: либо с использованием переменных Bash, либо с использованием самого синтаксиса Rake.
Переменная ENV
Если вы не играли с Bash раньше - или Bash звучит для вас как gobbledegook - давайте возьмем и начнем с самого начала. Bash в вашей оболочке предлагает два вида переменных: глобальные (aka environment) переменные и локальные. Оба записываются в верхнем регистре. Переменные окружения являются глобальными, что означает, что они доступны во всех оболочках и не исчезают, когда вы закрываете Bash, в отличие от локальных переменных, которые доступны только в текущей оболочке.
Переменные среды могут содержать данные, которые могут использоваться несколькими приложениями и часто используются в качестве удобного способа совместного использования параметров конфигурации. В отличие от этого, локальные переменные Bash - это просто локальные переменные. В нашем контексте использования Rake у вас есть возможность получить доступ как через Ruby, так и через командную строку.
FYI
Так же, если вы наберете env
или ENV
в своей оболочке, вы получите доступ к целой группе переменных окружения. Я отредактировал список, но для лучшего понимания того, какие переменные среды доступны и что они в себя включают, я призываю вас запустить это и у себя.
Shell
1 |
env |
Вывод
1 |
TERM_PROGRAM=Apple_Terminal |
2 |
TERM=screen-256color |
3 |
SHELL=/bin/bash |
4 |
TMUX=/private/var/folders/4z/3np9k5ks62b1xpbn_w_lmrgh0000gr/T/tmux-504/default,4146,0 |
5 |
EDITOR=vim |
6 |
LANG=en_US.UTF-8 |
7 |
TMUX_PANE=%1 |
8 |
is_vim=echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$" |
9 |
... |
10 |
... |
11 |
... |
Если вы хотите увидеть список локальных переменных Bash, вы можете выполнить set
.
Shell
1 |
( set -o posix ; set ) | less |
Команда set
дает вам намного больше выходных данных, но приведенное выше показывает вам сразу то что нужно.
Метод класса Ruby ENV
Ruby предлагает способ использования среды и локальных переменных Bash подобно хеш-подобному аксессуру. Для наших нужд, когда мы передаем переменную в задачу Rake, она будет локальной переменной Bash, которую вы можете найти в списке переменных, выполнив set
. Ruby может прочитать ее с помощью ENV['VARIABLE']
.
Shell
1 |
rake prepare_book BOOKTITLE='Confessions of a unicorn' |
Однако я хочу пояснить, что эта переменная не будет добавлена в список ENV, который использует ваша система, - то, что вы видели при вызове env
из оболочки. Чтобы добавить ее в этот список, вам нужно будет сделать export
. Это уже совсем другая история, но я подумал, что должен прояснить этот момент.
Некий Rakefile
1 |
task :prepare_book do |
2 |
book_title = ENV['BOOKTITLE'] || 'Working Title' |
3 |
puts "Do something with the #{book_title}" |
4 |
end
|
В этом определении задачи вы можете увидеть, как мы готовы принять или включить переменную, переданную в вызов задачи. Ruby ENV[BASHVARIABLE]
сделает за нас всю необходимую работу. Если BOOKTITLE
была глобальной переменной окружения, мы могли бы получить доступ к ней внутри этого определения задачи, а также с этим синтаксисом.
Синтаксис параметров Rake
Второй подход - использование чистого синтаксиса Rake. Вы просто передаете переменные в квадратные скобки. Этот подход лучше, и вы можете сохранять вещи более изолированными. Зачем подключать Bash, если Rake отлично справляется с этим? Кроме того, у вас нет переменных Bash, плавающих вокруг этого пути. Если вы хотите передать несколько аргументов в задачу, это будет намного более элегантно.
Shell
1 |
rake "create_mi6_agent[James, Bond, 007]" |
Некий Rakefile
1 |
task :create_mi6_agent, [:first_name, :last_name, :number] do |t, args| |
2 |
puts "Number #{args.number} is commander #{args.first_name} #{args.last_name}." |
3 |
end
|
Когда вы передаете больше аргументов, чем вы определили в своей задаче, вы можете просто получить к ним доступ через args
. args.extras
отображает массив всех дополнительных параметров. args.to_a
также показывает вам все параметры - в массиве.
Задачи, представляющие интерес
Ниже приведен краткий список задач Rake, связанных с Rails:
- db
- doc
- tmp
- stats
- notes
- about
- secret
- assets
- routes
db
Ниже приведены несколько полезных задач в пространстве имен db
для запуска миграции Active Record:
rake db:version
печатает текущую версию схемы. Результат выглядит примерно так:
1 |
Current version: 20160129135912 |
rake db:migrate
запускает последнюю миграцию (-и), которые еще не запущены. Вы также можете передать ему конкретную миграцию для запуска.
Shell
1 |
rake db:migrate VERSION=20080906120000 |
rake db:create
создает вашу базу данных. Если по умолчанию установлены базы данных разработки и тестирования.
1 |
db/development.sqlite3 |
2 |
db/test.sqlite3 |
rake db:test:prepare
проверяет, что миграции, которые уже запущены в вашей базе данных разработки, также запускаются для вашей тестовой базы данных. Если схема тестовой базы данных не синхронизирована с вашей базой данных разработки, это, конечно, не очень полезная задача.
rake db:drop:all
по умолчанию дропает как тестовые, так и базы данных разработки.
rake db:migrate:up
, rake db:migrate:down
запускает методы up
и down
для рассматриваемой миграции.
rake db:redo
гарантирует, что после выполнения миграции миграция будет обратимой. Он запускает сначала rake db:down
, а затем rake db:up
.
rake db:rollback
отменяет последнюю миграцию.
rake db:drop
по умолчанию дропает базу разработки и тестовую.
rake db:reset
сначала сбрасывает базы данных и снова устанавливает их, загружая схему и наполняя базу данных.
doc
rake doc:app
создает документацию в каталоге doc/app
. Он создает HTML-страницы о вашем исходном коде для удобного просмотра. Довольно круто!
Скриншот



rake doc:rails
создает документацию API в каталоге doc/api
- также как HTML-страницы. Удобно, если вы работаете в автономном режиме.
tmp
Каталог tmp
в корневом каталоге вашего приложения Rails - это место для временных файлов - наиболее заметных файлов для сеансов и кеша. rake tmp:create
устанавливает все, что вам нужно для работы с временными файлами. rake tmp:cache: clear
очищает каталог tmp/cache
. rake tmp:sessions:clear
очищает каталог tmp/sessions
.
stats
rake stats
дает вам хороший обзор вашего приложения.
1 |
+----------------------+-------+-------+---------+---------+-----+-------+ |
2 |
| Name | Lines | LOC | Classes | Methods | M/C | LOC/M | |
3 |
+----------------------+-------+-------+---------+---------+-----+-------+ |
4 |
| Controllers | 89 | 69 | 6 | 18 | 3 | 1 | |
5 |
| Helpers | 13 | 13 | 0 | 1 | 0 | 11 | |
6 |
| Models | 89 | 54 | 6 | 7 | 1 | 5 | |
7 |
| Mailers | 0 | 0 | 0 | 0 | 0 | 0 | |
8 |
| Javascripts | 25 | 0 | 0 | 0 | 0 | 0 | |
9 |
| Libraries | 0 | 0 | 0 | 0 | 0 | 0 | |
10 |
| Controller specs | 99 | 81 | 0 | 0 | 0 | 0 | |
11 |
| Feature specs | 14 | 11 | 0 | 0 | 0 | 0 | |
12 |
| Helper specs | 45 | 12 | 0 | 0 | 0 | 0 | |
13 |
| Model specs | 10 | 8 | 0 | 0 | 0 | 0 | |
14 |
| View specs | 60 | 48 | 0 | 0 | 0 | 0 | |
15 |
+----------------------+-------+-------+---------+---------+-----+-------+ |
16 |
| Total | 444 | 296 | 12 | 26 | 2 | 9 | |
17 |
+----------------------+-------+-------+---------+---------+-----+-------+ |
18 |
Code LOC: 136 Test LOC: 160 Code to Test Ratio: 1:1.2 |
notes
Вы можете оставить заметки в своем коде. Вы можете прикрепить их в своих комментариях с помощью TODO
, FIXME
, OPTIMIZE
.
Некий файл Ruby
1 |
# FIXME Something to fix here
|
2 |
class Agent < ActiveRecord::Base |
3 |
belongs_to :operation |
4 |
belongs_to :mission |
5 |
|
6 |
...
|
Когда вы запускаете rake notes
, Rake анализирует эти префиксы и получает список всех этих заметок из вашего кода.
Shell
1 |
app/models/agent.rb: |
2 |
* [1] [FIXME] Something to fix here |
Вы даже получите подробный список, где вы найдете их: каталог, имя файла, номер строки [Номер строки]
, все включено. Удивительно, правда?
about
rake about
дает вам обзор номеров версий для:
- Rails
- Ruby
- RubyGems
- Адаптер базы данных
- Версия схемы
- Middleware
- Корень приложения
и много другой полезной информации.
secret
Если вы параноик относительно своего ключа сеанса и хотите его заменить, rake secret
создаст для вас новый псевдослучайный ключ. Тем не менее, он не заменяет ключ для вас. Результат в оболочке выглядит следующим образом:
1 |
b40a74b94cd93fed370fd4f8f9333633c03990b7d9128383511de5240acf3fa6b6b07127e875814fdadb32f1aa44d69c4e82592b0ce97f763ea216a21e61881d |
ресурсы
rake assets:precompile
позволяет предварительно скомпилировать ваши ресурсы в папке public/assets
. Если вы хотите избавиться от старых ресурсов, просто используйте rake assets:clea
n. Наконец, запуск rake assets:clobber
удаляет весь каталог public/assets
.
routes
rake routes
наверно самая важная команда. Она показывает вам все маршруты в вашем приложении.
Заключение
Написание задач Rake, не зная, что происходит под капотом, становится довольно скучным занятием. Эта статья была небольшой разминкой и введением для людей, которые хотели заглянуть в Rake в первый раз.
Надеюсь, я охватил все основы, не будучи слишком сухими - в конце концов, Rake - это очень мощный инструмент, но в то же время это, возможно, не самая сексуальная игрушка. Однако это базовое знание Rake должно дать вам все, что вам нужно, чтобы стать опасным и расширить свои знания о задачах Rake, которые находятся в вашем распоряжении.