গ্রেডেল র্যাপারকে কেন ভিসিএসের কাছে প্রতিশ্রুতিবদ্ধ করা উচিত?


147

গ্রেডলের ডকুমেন্টেশন থেকে: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

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

থেকে: কীসের উত্স নিয়ন্ত্রণে থাকা উচিত নয়?

আমার মনে Generated filesহয় ভিসিএসে থাকা উচিত নয়।

কখন gradlewএবং gradle/gradle-wrapper.jarপ্রয়োজন হয়?

কেন না একটি সংরক্ষণ gradle versionমধ্যে build.gradleফাইল?


1
নীচের উত্তরগুলি প্রদত্ত একটি আকর্ষণীয় পার্শ্ব আলোচনা হতে পারে, যদি আপনি ক্রমাগত সংহতকরণের কিছু ফর্ম ব্যবহার করেন তবে এই ফাইলগুলির উপযোগিতা। কোনটি গ্রেড-র‌্যাপারের জন্য যাচাই করবে এবং সেখানে থাকলে এটি ব্যবহার করবে?
লিলবির্ডি

উত্তর:


124

কারণ গ্রেডেলের মোড়কের পুরো বিন্দুটি কখনও গ্রেড ইনস্টল না করে এবং এটি কীভাবে কাজ করে তা না জেনেও সক্ষম হতে হয়, ভিসিএস থেকে প্রকল্পটি ক্লোন করতে, কোন সংস্করণ থেকে ডাউনলোড করতে হবে, গ্রেডল স্ক্রিপ্টটি সম্পাদন করতে পারে রয়েছে এবং কোনও অতিরিক্ত পদক্ষেপ ছাড়াই প্রকল্পটি তৈরি করবে।

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


94
ওটা বোকামি. গ্রেডেল-র্যাপার.জারের ভিসিএসের প্রয়োজন হবে না। আপনার প্রয়োজনের পরে গ্রেডল কোনও সংস্করণ ডাউনলোড করতে সক্ষম হবে। এই সরঞ্জামচেইনের একটি ভিসিএস-তে কিছু করার নেই ... আমি বুঝতে পেরেছি আপনার উত্তরটি সঠিক, এবং এটি গ্রেডেলের নকশা। তবে এই নকশাটি অযৌক্তিক।
মার্ক প্লানো-লেসে

26
বিন্দুটি হ'ল আগে গ্রেডেল ইনস্টল না করে গ্রেডল ডাউনলোড করতে সক্ষম হব । ভিসিএসে 50KB-বৃহত ফাইল থাকতে সমস্যা কি?
জেবি নিজেট

59
সমস্যাটি হ'ল এটি প্রকল্পের অংশ নয়। প্রকল্পটি নির্মাণের জন্য এটি ব্যবহার করা একটি সরঞ্জাম। আপনি ভিসিএসে জেডিকে সংরক্ষণ করবেন না, তাই না? না সি সি আবেদনের জন্য জিসিসি? তাহলে আপনি কেন একটি গ্রেডল অংশ সঞ্চয় করবেন? যদি কোনও বিকাশকারী গ্র্যাডল নিজেই পড়তে বা ইনস্টল করতে না পারেন, তবে এটি অন্য সমস্যা।
মার্ক প্লানো-লেসে

26
সমস্যাটি আপনি এটি মনে করতে পারেন না, এটি প্রকাশের 2 বছর পরে, আপনার সফ্টওয়্যারটির ভি 1.0 সংস্করণ তৈরি করার জন্য গ্রেডলের কোন সংস্করণ ব্যবহার করা হয়েছিল, যে গ্রাহকের জন্য আপনার এখনও হটফিক্স রাখতে হবে যা এখনও এই 1.0 ব্যবহার করছে সংস্করণ এবং আপগ্রেড করতে পারে না। গ্রেডেলের মোড়কটি সমাধান করে যে: আপনি ভিসিএস থেকে 1.0 টি ট্যাগ ক্লোন করেছেন, গ্রেডলিউ ব্যবহার করে এটি নির্মাণ করুন এবং এটি গ্রেড সংস্করণ ব্যবহার করে যা 2 বছর আগে 1.0 সংস্করণটি তৈরি করতে ব্যবহৃত হয়েছিল।
জেবি নিজেট

33
আমি সম্মত হই যে গ্র্যাডল সংস্করণটি ব্যবহার করা উচিত প্রকল্পের কোথাও নির্দেশিত হওয়া দরকার। তবে গ্রেডল একটি বাহ্যিক সরঞ্জাম, একটি README বা আপনার তালিকাভুক্ত যে কোনও কিছুর সাথে তুলনামূলক কিছুই নয়। গ্রেডল ভিসিএসে কোনও জার সংরক্ষণ না করে সংশ্লিষ্ট সংস্করণটি নিজেই আনতে সক্ষম হবে।
মার্ক প্লানো-লেসেই

80

কারণ গ্রেডেল মোড়কের পুরো পয়েন্টটি কখনও গ্রেড ইনস্টল না করেই সক্ষম হতে হবে

একই যুক্তি জেডিকে-র পক্ষে যায়, আপনিও তা করতে চান? আপনি কি আপনার সমস্ত নির্ভরযোগ্য লাইব্রেরি প্রতিশ্রুতিবদ্ধ?

নতুন সংস্করণ প্রকাশিত হওয়ায় নির্ভরতাগুলি ধারাবাহিকভাবে আপগ্রেড করা উচিত। সুরক্ষা এবং অন্যান্য বাগ ফিক্সগুলি পেতে। এবং কারণ আপনি যদি এটির পিছনে চলে যান তবে আবার আপ টু ডেট পাওয়া খুব সময় সাশ্রয়ী কাজ হতে পারে।

যদি প্রতিটি নতুন রিলিজের জন্য গ্রেডেলের মোড়ক বাড়ানো হয় এবং এটি প্রতিশ্রুতিবদ্ধ হয় তবে রেপোটি খুব বড় হবে। বিতরণ করা ভিসিএসের সাথে কাজ করার সময় সমস্যাটি স্পষ্ট। যেখানে ক্লোনটি সমস্ত সংস্করণের সমস্ত সংস্করণ ডাউনলোড করবে।

, এবং এটি কীভাবে কাজ করে তা না জেনেও

একটি বিল্ড স্ক্রিপ্ট তৈরি করুন যা মোড়ক ডাউনলোড করে এবং এটি নির্মাণে ব্যবহার করে। স্ক্রিপ্টটি কীভাবে কাজ করে তা প্রত্যেকেরই জানা দরকার না, তাদের বাস্তবায়নের মাধ্যমে প্রকল্পটি তৈরির বিষয়ে একমত হতে হবে।

, কোথা থেকে এটি ডাউনলোড করবেন, কোন সংস্করণ

task wrapper(type: Wrapper) {
 gradleVersion = 'X.X' 
}

এবং তারপর

gradle wrapper

সঠিক সংস্করণটি ডাউনলোড করতে।

, ভিসিএস থেকে প্রকল্পটি ক্লোন করতে, এতে থাকা গ্রেডলিউ স্ক্রিপ্টটি কার্যকর করতে এবং কোনও অতিরিক্ত পদক্ষেপ ছাড়াই প্রকল্পটি তৈরি করতে।

উপরের পদক্ষেপগুলি দ্বারা সমাধান করা। গ্রেডের মোড়ক ডাউনলোড করা অন্য কোনও নির্ভরতা ডাউনলোড করা থেকে আলাদা নয়। স্ক্রিপ্টটি যে কোনও বর্তমান গ্রেডল র‍্যাপারের জন্য পরীক্ষা করতে স্মার্ট কৌতুক হতে পারে এবং কোনও নতুন সংস্করণ থাকলে কেবল এটি ডাউনলোড করুন।

যদি বিকাশকারী গ্র্যাডল এর ​​আগে কখনও ব্যবহার না করে থাকে এবং না বুঝতে পারে গ্র্যাডল দিয়ে প্রকল্পটি তৈরি করা হচ্ছে। তারপরে "গ্রেডলু বিল্ড" চালানোর তুলনায় "বিল্ড.শ" চালানো আরও সুস্পষ্ট।

আপনার সমস্ত কিছু যদি একটি বিল্ড.ড্রেডল ফাইলের গ্রেড সংস্করণ নম্বর ছিল তবে আপনার একটি রিডএমই দরকার প্রত্যেককে ব্যাখ্যা করে যে গ্রেড সংস্করণ এক্স অবশ্যই ইনস্টল হওয়া ইউআরএল ওয়াই থেকে ডাউনলোড করতে হবে,

না, আপনার একটি পুনর্নির্মাণের প্রয়োজন হবে না। আপনার একটি থাকতে পারে তবে আমরা বিকাশকারী এবং আমাদের যথাসম্ভব স্বয়ংক্রিয়ভাবে চালানো উচিত। স্ক্রিপ্ট তৈরি করা আরও ভাল।

এবং প্রতিবার সংস্করণ বৃদ্ধি পেলে আপনাকে এটি করতে হবে।

যদি বিকাশকারীরা সম্মত হন তবে সঠিক প্রক্রিয়াটি হ'ল:

  1. ক্লোন রেপো
  2. বিল্ড স্ক্রিপ্ট চালান

তারপরে সেখানে সর্বশেষ গ্রেডের মোড়কে আপগ্রেড করার কোনও সমস্যা নেই। যদি গত রান থেকে সংস্করণটি বাড়ানো হয় তবে স্ক্রিপ্টটি নতুন সংস্করণটি ডাউনলোড করতে পারে।


2
"নির্ভরতাগুলি ধারাবাহিকভাবে আপগ্রেড করা উচিত" " হ্যাঁ, একটি প্রতীক্ষিত দিকের দিকে। না, পিছনের দিকে তাকানোর দিকে। পুরানো বিল্ডটি পুনরুত্পাদন করতে আপনার নির্ভরতার নির্দিষ্ট সংস্করণ থাকতে হবে। গ্রেডল কিছু ধরণের প্রকল্পগুলিকে মোকাবেলায় দ্রুত এবং সহজ করে তোলে। এটি এমন একটি সংস্থার মধ্যে বিশৃঙ্খলা হবে যা পুনরুত্পাদন এবং নিরীক্ষণের প্রয়োজন।
লিলবির্ডি

3
আপনি কী বোঝাতে চেয়েছেন তা নিশ্চিত নয়। তবে আপনার যদি build.gradleসংস্করণ নিয়ন্ত্রণে থাকে এবং এতে আপনার কাছে থাকে: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } তারপরে gradle wrapperব্যবহৃত মোড়কটি ডাউনলোড করবেন এবং আপনি পুরানো বিল্ডটি পুনরুত্পাদন করতে পারবেন।
টমাস বিজেরে

1
নির্ভরতা সম্পর্কে আপনার লাইনের উল্লেখ ছিল, গ্রেড সংস্করণ নয়। অবশ্যই, আপনি চান আপনার গ্রন্থাগারগুলিতে সর্বশেষতম সুরক্ষা এবং বাগ ফিক্স থাকা উচিত তবে যখন আপনি কোনও পুরানো বিল্ড পুনরুত্পাদন করার চেষ্টা করছেন, সম্ভবত নিরীক্ষণ বা আইনী উদ্দেশ্যে। আপনার লাইব্রেরিগুলি এবং বিল্ডিং প্রক্রিয়াটি যদি সম্ভব হয় তবে বাইনারি অভিন্ন আউটপুট উত্পাদন করতে সক্ষম হতে চান। লাইব্রেরির নির্ভরতার মতো, কোনও গ্যারান্টি নেই যে বিল্ডিংয়ের সময় একটি নির্দিষ্ট সংস্করণ পাওয়া যাবে ... এটি এখন থেকে 2 সপ্তাহ বা এখন থেকে 2 দশক পরে। হ্যাঁ, এটি কিছু প্রকল্পের জন্য লাইব্রেরি এবং এসডিকে সমান।
লিলবির্ডি

3
আমি মনে করি র‌্যাপারটি মূলত historicতিহাসিক কারণে রয়েছে। শুরুতে সবাই ম্যাভেন ব্যবহার করছে এবং গ্রেডল কেউ ইনস্টল করেনি। অজানা অনুপ্রবেশকারী নির্ভরতা ইনস্টল করতে সহকর্মীকে প্ররোচিত করা কঠিন হবে, তাই মোড়ক তাদের বুটস্ট্র্যাপে সহায়তা করে। আজকাল প্রত্যেকেরই ইতিমধ্যে গ্রেডল রয়েছে, এবং র‍্যাপারটি অতিরিক্ত কাজ করে।
ফ্র্যাঙ্কলিন ইউ

1
আপনি কি gradle wrapperপ্রতিটি বিল্ডে ক্লোন করার পরে কার্যকর করার পরামর্শ দিচ্ছেন ? এটি মূলত মোড়কে অকেজো করে তোলে, কারণ এর পুরো বিষয়টি হ'ল প্রকল্পটি তৈরি করতে আপনাকে স্থানীয়ভাবে গ্র্যাডল ইনস্টল করতে হবে না !
জেরুস

41

আমি একটি সহজ পদ্ধতির সুপারিশ করতে চাই।

আপনার প্রকল্পের README- তে একটি নথি যা একটি ইনস্টলেশন পদক্ষেপের প্রয়োজন, যথা:

gradle wrapper --gradle-version 3.3

এটি গ্রেডল ২.৪ বা ততোধিকের সাথে কাজ করে। এটি "build.gradle" এ যুক্ত করার জন্য কোনও ডেডিকেটেড টাস্কের প্রয়োজন ছাড়াই একটি মোড়ক তৈরি করে।

এই বিকল্পের সাহায্যে সংস্করণ নিয়ন্ত্রণের জন্য এই ফাইলগুলি / ফোল্ডারগুলিকে উপেক্ষা করুন (চেক ইন করবেন না):

  • ./gradle
  • gradlew
  • gradlew.bat

মূল সুবিধাটি হ'ল উত্স নিয়ন্ত্রণে আপনাকে ডাউনলোড করা কোনও ফাইল চেক ইন করতে হবে না। এটি ইনস্টলেশন করার জন্য একটি অতিরিক্ত পদক্ষেপ ব্যয় করে। আমি মনে করি এটি মূল্যবান।


15
আপনার তখন মোড়কের দরকার হবে কেন? মোড়কের পুরো ধারণাটি হ'ল আপনি আপনার সিস্টেমে গ্রেড না করেই প্রকল্পটি তৈরি করতে পারেন।
এডিও

4
সুন্দর সমাধান। গিটে কোনও বাইনারি নেই এবং এখনও ব্যবহারের ক্ষমতা রয়েছে gradlew। @ এডিয়ো আপনার গ্রেডেলের একটি নির্দিষ্ট সংস্করণ ডাউনলোড এবং ব্যবহার করতে এটির প্রয়োজন হবে ।
কিরিল

3

"প্রকল্প" কি?

সম্ভবত এই আইডিয়মের একটি প্রযুক্তিগত সংজ্ঞা রয়েছে যা বিল্ড স্ক্রিপ্টগুলি বাদ দেয়। তবে আমরা যদি এই সংজ্ঞাটি মেনে নিই, তবে আমাদের অবশ্যই বলতে হবে আপনার "প্রকল্প" আপনার সংস্করণ করার জন্য প্রয়োজনীয় সমস্ত জিনিস নয়!

তবে আমরা যদি বলি "আপনার প্রকল্প" আপনি যা করেছেন তা সবই । তারপরে আমরা বলতে পারি আপনাকে অবশ্যই এটি অন্তর্ভুক্ত করতে হবে এবং এটি কেবল ভিসিএসে অন্তর্ভুক্ত করা উচিত ।

এটি খুব তাত্ত্বিক এবং আমাদের উন্নয়ন কাজের ক্ষেত্রে ব্যবহারিক নাও হতে পারে। সুতরাং আমরা এটিকে " আপনার প্রকল্পটি প্রতিটি ফাইল (বা ফোল্ডার) এ সরাসরি সম্পাদনা করতে হবে " তে এটি পরিবর্তন করে

"প্রত্যক্ষ" অর্থ "অপ্রত্যক্ষভাবে নয়" এবং "অপ্রত্যক্ষভাবে" অর্থ অন্য ফাইল সম্পাদনা করার মাধ্যমে এবং তারপরে একটি প্রভাব এই ফাইলটিতে প্রতিফলিত হবে

সুতরাং আমরা ওপি যা বলেছিলাম একইভাবে পৌঁছেছি (এবং এখানে বলা হয় ):

আমি মনে করি জেনারেটেড ফাইলগুলি ভিসিএসে থাকা উচিত নয়।

হ্যাঁ. কারণ আপনি এগুলি তৈরি করেন নি। সুতরাং তারা দ্বিতীয় সংজ্ঞা অনুযায়ী "আপনার প্রকল্পের" অংশ নয়।


এই ফাইলগুলি সম্পর্কে ফলাফল কী:

  • build.gradle : হ্যাঁ আমাদের এটি সম্পাদনা করা দরকার। আমাদের কাজের সংস্করণ করা উচিত।

    দ্রষ্টব্য: আপনি যেখানে এটি সম্পাদনা করবেন সেখানে কোনও পার্থক্য নেই। আপনার পাঠ্য সম্পাদক পরিবেশে বা প্রকল্প কাঠামো জিইউআই পরিবেশে হোক। যাইহোক আপনি সরাসরি এটি করছেন !

  • গ্রেড- Wrapper.properties : হ্যাঁ। আমাদের এই ফাইলটিতে কমপক্ষে গ্রেডল সংস্করণ নির্ধারণ করতে হবে।

  • গ্রেডলে-র্যাপার.জার এবং গ্রেডলিউ [.বাট] : আমি এই মুহূর্ত অবধি আমার কোনও উন্নয়ন কাজের মধ্যে এগুলি তৈরি বা সম্পাদনা করি নি! তাহলে উত্তর হল না". আপনি যদি এটি করেন তবে উত্তরটি সেই কাজটি সম্পর্কে আপনার সম্পর্কে "হ্যাঁ" এবং আপনি সম্পাদিত একই ফাইলটির বিষয়ে।


সর্বশেষ কেস সম্পর্কিত গুরুত্বপূর্ণ নোট ব্যবহারকারী আপনার রেপো ক্লোনস, উপর এই কমান্ডটি চালাবার প্রয়োজন রেপো এর<root-directory> জন্য স্বয়ং-জেনারেট ফাইল মোড়কের:

> gradle wrapper --gradle-version=$v --distribution-type=$distType

$vএবং গ্রেড-র‍্যাপার.প্রোপার্টি$distType থেকে নির্ধারিত :

distributionUrl=https\://services.gradle.org/distributions/gradle-{$v}-{$distType}.zip

আরও তথ্যের জন্য https://gradle.org/install/ দেখুন ।

gradleএক্সিকিউটেবল bin/gradle[.bat]স্থানীয় বিতরণ হয়। এটির প্রয়োজন নেই যে স্থানীয় বিতরণ রেপোতে নির্ধারিত সমান হবে। র‍্যাপার ফাইলগুলি তৈরি হওয়ার পরে gradlew[.bat]নির্ধারিত গ্রেডেল বিতরণ স্বয়ংক্রিয়ভাবে ডাউনলোড করতে পারে (স্থানীয়ভাবে উপস্থিত না থাকলে)। তারপরে তার অবশ্যই gradleউপরের নির্দেশাবলী ব্যবহার করে নতুন এক্সিকিউটেবল (ডাউনলোড করা বিতরণে) ব্যবহার করে মোড়কের ফাইলগুলি পুনরায় জেনারেট করতে হবে ।


দ্রষ্টব্য: উপরের নির্দেশাবলীতে, স্থানীয়ভাবে স্থানীয়ভাবে কমপক্ষে একটি গ্রেডেল বিতরণ রয়েছে বলে মনে করা হচ্ছে (উদাঃ ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10)। এটি প্রায় সমস্ত বাস্তব কেস কভার করে। তবে ব্যবহারকারীর ইতিমধ্যে কোনও বিতরণ না থাকলে কী হবে?

তিনি / সে .propertiesফাইলটিতে ইউআরএল ব্যবহার করে ম্যানুয়ালি এটি ডাউনলোড করতে পারে । কিন্তু যদি তিনি / সে পথ যে এটি সনাক্ত না মোড়কের প্রত্যাশিত, মোড়কের এটি পুনরায় ডাউনলোড হবে! প্রত্যাশিত পথটি সম্পূর্ণ অনুমানযোগ্য তবে বিষয়টির বাইরে ( সবচেয়ে জটিল অংশের জন্য এখানে দেখুন )।

কয়েকটি সহজ (তবে নোংরা) উপায়ও রয়েছে। উদাহরণস্বরূপ, তিনি / অন্য কোনও স্থানীয় / রিমোট রিপোজিটরি থেকে তার / তার সংগ্রহস্থলে র্যাপার ফাইলগুলি ( ফাইল ব্যতীত .properties) অনুলিপি করতে পারেন এবং তারপরে তার সংগ্রহস্থলটিতে চালনা gradlewকরতে পারেন। এটি স্বয়ংক্রিয়ভাবে উপযুক্ত বিতরণ ডাউনলোড করবে।


0

গ্রেডল ডক্স অনুসারে, ভিসিএসে যুক্ত gradle-wrapper.jarকরা আশা করা হয় যেহেতু বিকাশকারীদের জন্য গ্র্যাডেল র্যাপার উপলব্ধ করা গ্রেডল পদ্ধতির অংশ:

অন্যান্য বিকাশকারী এবং কার্যকর পরিবেশের জন্য র্যাপার ফাইলগুলি উপলভ্য করতে আপনাকে সেগুলি সংস্করণ নিয়ন্ত্রণে পরীক্ষা করতে হবে। জেআর ফাইল সহ সমস্ত র‍্যাপার ফাইলগুলি আকারে খুব ছোট। সংস্করণ নিয়ন্ত্রণে JAR ফাইল যুক্ত করা প্রত্যাশিত। কিছু সংস্থা প্রকল্পগুলিকে সংস্করণ নিয়ন্ত্রণে বাইনারি ফাইল জমা দেওয়ার মঞ্জুরি দেয় না। এই মুহুর্তে পদ্ধতির বিকল্প বিকল্প নেই।


0

পুরানো প্রশ্ন, নতুন উত্তর। যদি আপনি প্রায়শই গ্রেড আপগ্রেড না করেন (আমাদের বেশিরভাগই তা করেন না), এটি ভিসিএসের কাছে কমিট করা আরও ভাল। এবং আমার প্রধান কারণ হ'ল সিআই সার্ভারে বিল্ড স্পিড বৃদ্ধি করা। আজকাল, বেশিরভাগ প্রকল্পগুলি প্রতিবারই বিভিন্ন সার্ভারের উদাহরণস্বরূপ সিআই সার্ভারগুলি দ্বারা নির্মিত এবং ইনস্টল হচ্ছে।

যদি আপনি এটি প্রতিশ্রুতি না দেন, সিআই সার্ভার প্রতিটি বিল্ডের জন্য একটি জার ডাউনলোড করবে এবং এটি বিল্ড সময়কে উল্লেখযোগ্যভাবে বাড়িয়ে তুলবে। এই সমস্যাটি হ্যান্ডেল করার অন্যান্য উপায় রয়েছে তবে আমি এটি বজায় রাখা সবচেয়ে সহজ বলে মনে করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.