রেক টাস্কের মধ্যে থেকে রেকে কাজগুলি কীভাবে চালানো যায়?


410

আমার কাছে একটি রেকফিল রয়েছে যা গ্লোবাল ভেরিয়েবল অনুসারে প্রকল্পটি দুটি উপায়ে সংকলন করে $build_type, যা হতে পারে :debugবা :release(ফলাফলগুলি পৃথক ডিরেক্টরিতে যেতে পারে ):

task :build => [:some_other_tasks] do
end

আমি এমন একটি টাস্ক তৈরি করতে চাই যা প্রকল্পটি উভয় কনফিগারেশনের পরিবর্তে সংকলিত করে, এরকম কিছু:

task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    # call task :build with all the tasks it depends on (?)
  end
end

কোনও কাজকে কল করার কোনও উপায় কি যেন এটি কোনও পদ্ধতি? বা আমি কীভাবে অনুরূপ কিছু অর্জন করতে পারি?


7
কোনটি উত্তর?
নুরেটিন

আমি সম্প্রদায়ে ভোট দিয়ে যাব এবং 221 বার (লেখার সময়) আপলোডকৃত উত্তরটি বেছে নেব। আসল পোস্টারটি SO
MPritchard 7'13


এফওয়াইআই, এর মতো কিছু ব্যবহার করা ব্যবহারের Rake::Task["build"].invokeচেয়ে আরও বেশি পারফরম্যান্স হতে পারে system rake buildকারণ এটিতে একটি নতুন থ্রেড তৈরি করতে হবে না এবং রেল পরিবেশকে লোড করতে হবে না, যা system rake buildকরতে হবে।
জোশুয়া পিন্টার

উত্তর:


639

আপনার যদি কোনও পদ্ধতি হিসাবে আচরণ করার প্রয়োজন হয় তবে একটি আসল পদ্ধতি ব্যবহার সম্পর্কে কীভাবে?

task :build => [:some_other_tasks] do
  build
end

task :build_all do
  [:debug, :release].each { |t| build t }
end

def build(type = :debug)
  # ...
end

আপনি যদি বরং rakeউক্ত প্রবাদগুলিকে আঁকড়ে রাখতে চান তবে অতীত উত্তরগুলি থেকে সংকলিত আপনার সম্ভাবনাগুলি এখানে:

  • এটি সর্বদা কার্য সম্পাদন করে তবে এটি নির্ভরতাগুলি কার্যকর করে না:

    Rake::Task["build"].execute
  • এটি নির্ভরশীলতাগুলি কার্যকর করে, তবে কেবলমাত্র যদি এটি ইতিমধ্যে না চাওয়া হয় তবে কাজটি সম্পাদন করে:

    Rake::Task["build"].invoke
  • এটি প্রথমে টাস্কটির ইতিমধ্যে_আবাদযুক্ত অবস্থার পুনরায় সেট করে, কাজটিকে আবার কার্যকর করার অনুমতি দেয়, নির্ভরতা এবং সমস্ত:

    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
    
  • মনে রাখবেন যে ইতিমধ্যে অনুরোধ করা নির্ভরতাগুলি পুনরায় সক্ষম না করা হলে স্বয়ংক্রিয়ভাবে পুনরায় কার্যকর করা হবে না। রেকে> = 10.3.2 এ, আপনি তাদের আবার সক্ষম করার জন্য নিম্নলিখিতগুলি ব্যবহার করতে পারেন:

    Rake::Task["build"].all_prerequisite_tasks.each(&:reenable)

96
মনে রাখবেন যে আপনার কাজগুলি যদি নেমস্পেসে থাকে, আপনি যখন কাজটি শুরু করবেন তখন আপনাকে অবশ্যই অবশ্যই নেমস্পেসটি অন্তর্ভুক্ত করতে হবে। যেমন। Rake::Task['db:reset'].invoke
ডেভিড টুয়েট

126
যদি প্রশ্নগুলির মধ্যে কাজটি আর্গুমেন্ট নেয়, আপনি এগুলিকে # ইনভোকের পক্ষে আর্গুমেন্ট হিসাবে পাস করতে পারেন। যেমন। Rake::Task['with:args'].invoke("pizza")
ট্রটার

26
আপনার যদি পরিবেশের পরিবর্তনশীল সেট করতে হয় তবে ডাকটি আহ্বানের আগে তা করুন। উদাহরণস্বরূপ: আরও ব্যাখ্যার জন্য এখানেENV['VERSION'] = '20110408170816'; Rake::Task['db:migrate'].invoke দেখুন ।
মাইকেল স্টালকার

13
আমি সম্প্রতি আবিষ্কার করেছি #reenable()যে প্রাক-রিক্সগুলি পুনরায় সক্ষম করে না এবং এটির প্রয়োজন ছিল। এই ছাড়াও Rake (> = 10.3.2) এর, #all_prerequisite_tasks()সহ সব কর্ম পুনরুক্তি হবে, প্রাক req এর প্রাক req এর। সুতরাং,Rake::Task[task].all_prerequisite_tasks.each &:reenable
রিচার্ড মাইকেল

4
@ কেচএইচ, আপনি কি এগুলি একসাথে স্ট্রিং করতে পারেন ( rake db:reset db:migrateউদাহরণস্বরূপ কমান্ডলাইনের মতো )। আপনি কি এর মতো কিছু করতে পারেন: Rake::Task["db:reset", "db:migrate"].invoke
জেফ

125

উদাহরণ স্বরূপ:

Rake::Task["db:migrate"].invoke

6
এটি কাজটি কেবল তখনই অনুরোধ করে যদি এটি ইতিমধ্যে না চাওয়া হয়। তবে আমার অন্যান্য সমস্ত কার্যগুলি টাস্কগুলির সাথে ডাকা উচিত যা এটি দুবার নির্ভর করে।

58
task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
  end
end

এটি আপনাকে বাছাই করা উচিত, কেবল একই জিনিসটি আমার নিজের প্রয়োজন।


এটি কার্যকরী, তবে খুব ভার্জোজ। নিশ্চয়ই এর চেয়ে ভাল আর কিছু নেই?
kch

13
task :invoke_another_task do
  # some code
  Rake::Task["another:task"].invoke
end

আমার এর মতো সমাধানের প্রয়োজনের একটি কারণ হ'ল র‌্যাক টাস্ক লোড করতে অনেক সময় লাগে। উপরের মতো একটি সমাধান কার্যকর করে, এটি কি লোডিংয়ের সময় সাশ্রয় করবে?
দিপান মেহতা

11
task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    Rake::Task["build"].execute
  end
end

এটি কাজ করে না, কারণ এটি কেবলমাত্র শরীরের সম্পাদন করে: কার্য তৈরি করুন এবং তার উপর নির্ভর করে যে কাজগুলিকে ডাইবেন না।

4

আপনি যদি কোনও ব্যর্থতা নির্বিশেষে প্রতিটি কাজ চালাতে চান তবে আপনি এর মতো কিছু করতে পারেন:

task :build_all do
  [:debug, :release].each do |t| 
    ts = 0
    begin  
      Rake::Task["build"].invoke(t)
    rescue
      ts = 1
      next
    ensure
      Rake::Task["build"].reenable # If you need to reenable
    end
    return ts # Return exit code 1 if any failed, 0 if all success
  end
end

-1

আমি প্রস্তাব করব যে সাধারণ ডিবাগ তৈরি না করা এবং কাজগুলি প্রকাশের জন্য যদি প্রকল্পটি সত্যিই এমন কিছু হয় যা সংকলিত হয় এবং ফলস্বরূপ ফাইল হয়। আপনার ফাইল-টাস্কগুলির সাথে যাওয়া উচিত যা আপনার উদাহরণ হিসাবে যথেষ্ট কার্যকর, যেমন আপনি উল্লেখ করেছেন যে আপনার আউটপুট বিভিন্ন ডিরেক্টরিতে চলে। বলুন আপনার প্রকল্পটি / ডিবাগ / টেস্টআউট এবং আউট / রিলিজ / টেস্টআউট আউট / ডিবিগ / টেস্ট.আউট করার জন্য একটি টেস্ট.ক্র.

WAYS = ['debug', 'release']
FLAGS = {}
FLAGS['debug'] = '-g'
FLAGS['release'] = '-O'
def out_dir(way)
  File.join('out', way)
end
def out_file(way)
  File.join(out_dir(way), 'test.out')
end
WAYS.each do |way|
  desc "create output directory for #{way}"
  directory out_dir(way)

  desc "build in the #{way}-way"
  file out_file(way) => [out_dir(way), 'test.c'] do |t|
    sh "gcc #{FLAGS[way]} -c test.c -o #{t.name}"
  end
end
desc 'build all ways'
task :all => WAYS.map{|way|out_file(way)}

task :default => [:all]

এই সেটআপটি ব্যবহার করা যেতে পারে:

rake all # (builds debug and release)
rake debug # (builds only debug)
rake release # (builds only release)

এটি যেমন চাওয়া হয়েছে তেমন আরও কিছু করে তবে আমার পয়েন্টগুলি দেখায়:

  1. প্রয়োজনীয় হিসাবে আউটপুট ডিরেক্টরি তৈরি করা হয়।
  2. ফাইলগুলি কেবল প্রয়োজন হলে পুনরায় সংযুক্ত করা হয় (এই উদাহরণটি কেবলমাত্র টেস্ট.সি. ফাইলগুলির সাদামাটা জন্য সঠিক)।
  3. আপনি যদি রিলিজ বিল্ড বা ডিবাগ বিল্ডটি ট্রিগার করতে চান তবে আপনার সমস্ত কাজ সহজেই হাতে রয়েছে।
  4. এই উদাহরণে ডিবাগ এবং রিলিজ-বিল্ডের মধ্যে ছোট পার্থক্য সংজ্ঞায়নের একটি উপায় অন্তর্ভুক্ত রয়েছে।
  5. গ্লোবাল ভেরিয়েবলের সাথে প্যারামিটারাইজড এমন বিল্ড-টাস্কটিকে পুনরায় সক্ষম করার দরকার নেই, কারণ এখন বিভিন্ন বিল্ডগুলির আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা টাস্ক থাকে বিল্ড-টাস্কের কোডরিয়জটি বিল্ড-টাস্কগুলি সংজ্ঞায়িত করতে কোডটি পুনরায় ব্যবহার করে সম্পন্ন করা হয়। দেখুন লুপ কীভাবে একই কাজটি দু'বার সম্পাদন করে না, বরং এর পরিবর্তে কার্য তৈরি করেছে, যা পরে চালিত করা যেতে পারে (হয় সমস্ত-কার্য দ্বারা বা রেক কমান্ডলাইনে তাদের মধ্যে একটি চয়ন করা যেতে পারে)।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.