التحقيق في انتهاكات الاقتراض والترخيص المحتملة في كود Java على GitHub

اسمي ياروسلاف غولوبيف ، أعمل في JetBrains Research ، في مختبر أساليب التعلم الآلي في هندسة البرمجيات . كتب بعض زملائي هنا بالفعل عن مشاريعهم (على سبيل المثال ، نصائح للدورات عبر الإنترنت ). الهدف العام لمجموعتنا هو جعل عمل المبرمجين أسهل وأكثر ملاءمة وأكثر كفاءة باستخدام البيانات حول ماذا وكيف يبرمج الناس. ومع ذلك ، فإن عملية إنشاء منتجات برمجية لا تتكون فقط من كتابة التعليمات البرمجية - فهناك أيضًا وثائق وتعليقات ومناقشات عمل وغير ذلك الكثير - ومع كل هذا يمكن ويجب مساعدة الأشخاص أيضًا.



أحد هذه الجوانب الجانبية لتطوير البرمجيات هو ترخيص الكود. بالنسبة لبعض المطورين ، يبدو الترخيص وكأنه غابة مظلمة إلى حد ما ، فهم يحاولون عدم الدخول فيه وإما أنهم لا يفهمون الاختلافات وقواعد الترخيص بشكل عام ، أو أنهم يعرفون عنها بشكل سطحي إلى حد ما ، ولهذا السبب يمكنهم ارتكاب أنواع مختلفة من الانتهاكات. وأكثر هذه الانتهاكات شيوعاً هو نسخ (إعادة استخدام) وتعديل المدونة بما ينتهك حقوق مؤلفها.



تبدأ أي مساعدة للأشخاص بالتحقيق في الوضع الحالي - أولاً ، يعد جمع البيانات ضروريًا لإمكانية مزيد من التشغيل الآلي ، وثانيًا ، سيسمح لنا تحليلهم بمعرفة الخطأ الذي يفعله الأشخاص بالضبط. في هذه المقالة ، سأصف مثل هذه الدراسة: سأقدم لك الأنواع الرئيسية لتراخيص البرامج (بالإضافة إلى بعض التراخيص النادرة ولكن الجديرة بالملاحظة) ، وسأتحدث عن تحليل الكود والبحث عن الاقتراضات بكمية كبيرة من البيانات ، وسأقدم لك النصائح حول كيفية التعامل بشكل صحيح مع التراخيص في الكود. وتجنب الأخطاء الشائعة.



مقدمة لترخيص الكود



على الإنترنت ، وحتى في Habré ، توجد بالفعل أوصاف مفصلة للتراخيص ، لذلك سنقتصر على عرض عام موجز للموضوع الضروري لفهم جوهر الدراسة.



سنتحدث فقط عن ترخيص البرامج مفتوحة المصدر . أولاً ، يرجع هذا إلى حقيقة أنه في هذا النموذج يمكننا بسهولة العثور على الكثير من البيانات المتاحة ، وثانيًا ، مصطلح "البرامج مفتوحة المصدر"يمكن أن يكون مضللاً. عند تنزيل برنامج ملكية مشترك وتثبيته من موقع الشركة على الويب ، يُطلب منك الموافقة على شروط الترخيص. بالطبع ، لا تقرأها عادة ، لكنك تفهم بشكل عام أن هذه ملكية فكرية لشخص ما. في الوقت نفسه ، عندما يدخل المطورون مشروعًا على GitHub ويرون جميع الملفات المصدر ، يكون الموقف تجاههم مختلفًا تمامًا: نعم ، هناك نوع من الترخيص هناك ، لكنه مفتوح المصدر ، والبرنامج مفتوح المصدر ، مما يعني أنه يمكنك الحصول على و افعل ما تريد صحيح؟ لسوء الحظ ، ليس كل شيء بهذه البساطة.



كيف يعمل الترخيص؟ لنبدأ بالتقسيم الأكثر عمومية للحقوق:







إذا انتقلت من اليمين إلى اليسار ، فسيكون الأول سرًا تجاريًا ، متبوعًا بتراخيص الملكية - لن نأخذها في الاعتبار. في مجال البرمجيات مفتوحة المصدر ، يمكن التمييز بين ثلاث فئات (حسب درجة الزيادة في الحريات): التراخيص التقييدية ( الحقوق المتروكة ) ، والتراخيص غير المقيدة ( المسموح بها ، والتراخيصية) والملك العام.(وهي ليست ترخيصًا ، ولكنها طريقة لمنح الحقوق). لفهم الفرق بينهما ، من المفيد معرفة سبب ظهورهما. إن مفهوم المجال العام قديم قدم العالم - فالمبدع يرفض تمامًا أي حقوق ويسمح له بفعل ما يريد بمنتجه. ومع ذلك ، من الغريب أن هذه الحرية تولد عدم الحرية - بعد كل شيء ، يمكن لشخص آخر أن يأخذ مثل هذا الإبداع ، ويغيره قليلاً ويفعل "أي شيء" به - بما في ذلك إغلاقها وبيعها. تم إنشاء تراخيص Copyleft مفتوحة المصدر على وجه التحديد لحماية الحرية - من موقعها في الصورة يمكنك أن ترى أنها تهدف إلى الحفاظ على التوازن: للسماح باستخدام المنتج وتغييره وتوزيعه ، ولكن ليس لقفله ، وتركه مجانًا. أيضًا ، حتى لو كان الكاتب لا يمانع في سيناريو الإغلاق والبيع ،تختلف مفاهيم الملك العام من بلد إلى آخر ، وبالتالي يمكن أن تخلق تعقيدات قانونية. لتجنبها ، يتم استخدام تراخيص متساهلة بسيطة.



فما الفرق بين الرخص المتروكة والحقوق المتروكة؟ مثل كل شيء في موضوعنا ، هذا السؤال محدد تمامًا ، وهناك استثناءات ، ولكن إذا قمت بالتبسيط ، فإن التراخيص المسموح بها لا تفرض قيودًا على ترخيص المنتج المعدل. بمعنى أنه يمكنك أخذ مثل هذا المنتج وتغييره ووضعه في مشروع بموجب ترخيص مختلف - حتى ترخيص خاص. يتمثل الاختلاف الرئيسي عن المجال العام هنا في أغلب الأحيان في الالتزام بالحفاظ على التأليف وذكر المؤلف الأصلي. أشهر التراخيص المسموح بها هي تراخيص MIT و BSD و Apache .... تشير العديد من الدراسات إلى معهد ماساتشوستس للتكنولوجيا باعتباره الترخيص المفتوح المصدر الأكثر شيوعًا بشكل عام ، ويلاحظ أيضًا النمو الكبير في شعبية ترخيص Apache-2.0 منذ إنشائه في عام 2004 (على سبيل المثال ، دراسة Java ).



غالبًا ما تفرض تراخيص الحقوق المتروكة قيودًا على توزيع المنتجات الثانوية وتعديلها - تحصل على منتج بحقوق معينة ، ويجب "تشغيله بشكل أكبر" ، مع منح جميع المستخدمين نفس الحقوق. يعني هذا عادةً التزامًا بإعادة توزيع البرنامج بموجب نفس الترخيص وتوفير الوصول إلى شفرة المصدر. بناءً على هذه الفلسفة ، أنشأ ريتشارد ستالمان أول وأشهر رخصة حقوق متروكة ، وهي رخصة جنو العمومية (GPL)). هي التي توفر أقصى حماية من الحرية للمستخدمين والمطورين في المستقبل. أوصي بقراءة تاريخ حركة ريتشارد ستالمان من أجل البرمجيات الحرة ، إنها مثيرة جدًا للاهتمام.



هناك صعوبة واحدة مع رخص الحقوق المتروكة - أنها تنقسم عادة إلى قوي و ضعيف الحقوق المتروكة. إن الحقوق المتروكة القوية هي بالضبط ما تم وصفه أعلاه ، بينما الحقوق المتروكة الضعيفة توفر تنازلات واستثناءات متنوعة للمطورين. أشهر مثال على مثل هذا الترخيص هو رخصة جنو العمومية الصغرى (LGPL): مثل إصداره الأقدم ، فإنه يسمح لك بتعديل وإعادة توزيع الكود فقط إذا احتفظت بهذا الترخيص ، ومع ذلك ، مع الارتباط الديناميكي (باستخدامه كمكتبة في تطبيق ما) يمكن حذف هذا المطلب. بمعنى آخر ، إذا كنت ترغب في استعارة شفرة المصدر من هنا أو تغيير شيء ما ، فاحرص على مراعاة الحقوق المتروكة ، ولكن إذا كنت ترغب فقط في استخدامه كمكتبة ارتباط ديناميكي ، فيمكنك القيام بذلك في أي مكان.



الآن بعد أن اكتشفنا التراخيص بأنفسنا ، يجب أن نتحدث عن مدى توافقها ، لأن الانتهاكات التي نريد منعها تكمن فيها (أو بالأحرى غيابها). يجب أن يكون أي شخص كان مهتمًا بهذا الموضوع قد صادف مخططات توافق الترخيص المشابهة لهذا:







من نظرة واحدة على مثل هذا المخطط ، يمكن أن تختفي أي رغبة في فهم التراخيص. في الواقع ، هناك العديد من تراخيص المصادر المفتوحة ، ويمكن العثور على قائمة شاملة إلى حد ما ، على سبيل المثال ، هنا . في الوقت نفسه ، كما سترى أدناه في نتائج دراستنا ، تحتاج إلى معرفة مبلغ محدود للغاية (بسبب توزيعها غير المتكافئ للغاية) ، وحتى عدد أقل من القواعد التي يجب تذكرها من أجل الامتثال لجميع شروطهم. إن الموجه العام لهذا المخطط بسيط للغاية: في مصدر كل شيء يوجد المجال العام ، وخلفه توجد تراخيص متساهلة ، ثم حقوق متروكة ضعيفة ، وأخيراً ، حقوق متروكة قوية ، والتراخيص متوافقة "صحيحة": في مشروع الحقوق المتروكة ، يمكنك إعادة استخدام الكود بموجب ترخيص مسموح به ، ولكن ليس العكس. - كل شيء منطقي.



وهنا قد يطرح السؤال: ماذا لو لم يكن لدى الكود ترخيص؟ ما القواعد التي يجب اتباعها بعد ذلك؟ هل يمكن نسخ هذا الرمز؟ هذا في الواقع سؤال مهم جدا. على الأرجح ، إذا كان الرمز مكتوبًا على سياج ، فيمكن اعتباره ملكية عامة ، وإذا كان مكتوبًا على الورق في زجاجة ، والتي تم تثبيتها في جزيرة صحراوية (بدون حقوق الطبع والنشر) ، فيمكن ببساطة أخذها واستخدامها. عندما يتعلق الأمر بالمنصات الكبيرة والراسخة مثل GitHub أو StackOverflow ، فإن الأمور ليست بهذه البساطة ، لأنه بمجرد استخدامها ، فإنك توافق تلقائيًا على شروط الاستخدام الخاصة بها. في الوقت الحالي ، دعنا نترك ملاحظة في رؤوسنا ونعود إليها لاحقًا - بعد كل شيء ، ربما يكون هذا أمرًا نادرًا ولا يوجد أي رمز عمليًا بدون ترخيص؟



بيان المشكلة والمنهجية



والآن بعد أن عرفنا معنى كل المصطلحات ، فلنكن واضحين بشأن ما نريد معرفته.



  • ما مدى شيوع نسخ الكود في البرامج مفتوحة المصدر؟ هل هناك العديد من النسخ في الكود بين المشاريع مفتوحة المصدر ؟
  • ما هي التراخيص الموجودة تحتها؟ ما هي أكثر التراخيص شيوعًا؟ هل يحتوي الملف على تراخيص متعددة مرة واحدة؟
  • ما هي أكثر عمليات الاقتراض الممكنة شيوعًا ، أي تحويلات الرمز من ترخيص إلى آخر؟
  • ما هي الانتهاكات المحتملة الأكثر شيوعًا ، أي انتقالات الكود المحظورة بموجب شروط الترخيص الأصلي أو الترخيص المستلم؟
  • ما هو الأصل المحتمل لأجزاء الكود الفردية؟ ما هي احتمالية نسخ هذا الجزء من الشفرة بشكل مخالف؟


لإجراء مثل هذا التحليل ، نحتاج إلى:



  1. أنشئ مجموعة بيانات من عدد كبير من المشاريع مفتوحة المصدر.
  2. ابحث عن نسخ مقتطفات من التعليمات البرمجية بينهم.
  3. حدد تلك الحيوانات المستنسخة التي يمكن استعارتها حقًا.
  4. لكل جزء من التعليمات البرمجية ، حدد معلمتين - ترخيصه ووقت آخر تعديل له ، وهو أمر ضروري لمعرفة أي جزء في زوج من النسخ المستنسخة أقدم وأيها أصغر ، وبالتالي - من يمكنه النسخ من من.
  5. تحديد الانتقالات الممكنة بين التراخيص المسموح بها وأيها غير مسموح به.
  6. حلل جميع البيانات التي تم الحصول عليها للإجابة على الأسئلة أعلاه.


الآن دعونا نلقي نظرة فاحصة على كل خطوة.



جمع البيانات



من المريح جدًا بالنسبة لنا أنه من السهل في الوقت الحاضر الوصول إلى الكثير من المصادر المفتوحة باستخدام GitHub. لا يحتوي فقط على الكود نفسه ، بل يحتوي أيضًا على تاريخ تغييراته ، وهو أمر مهم جدًا لهذه الدراسة: من أجل معرفة من يمكنه نسخ الكود من ، تحتاج إلى معرفة متى تمت إضافة كل جزء إلى المشروع.



لجمع البيانات ، عليك أن تقرر لغة البرمجة المدروسة. الحقيقة هي أنه يتم البحث عن النسخ المستنسخة في إطار لغة برمجة واحدة: عند التحدث عن انتهاك الترخيص ، يكون من الصعب تقييم إعادة كتابة خوارزمية موجودة إلى لغة أخرى. هذه المفاهيم المعقدة محمية ببراءات الاختراع ، بينما نتحدث في بحثنا عن المزيد من النسخ والتعديل النموذجي. اخترنا Java لأنها واحدة من أكثر اللغات استخدامًا وتحظى بشعبية خاصة في تطوير البرامج التجارية - وفي هذه الحالة تكون انتهاكات الترخيص المحتملة مهمة بشكل خاص.



لقد اتخذنا كأساس لأرشيف Git العام الحالي ، والذي جمع في بداية عام 2018 جميع المشاريع على GitHub التي تضم أكثر من 50 نجمة. اخترنا جميع المشاريع التي تحتوي على سطر واحد على الأقل في Java وقمنا بتنزيلها بسجل كامل للتغييرات. بعد تصفية المشاريع التي تم نقلها أو لم تعد متوفرة ، يوجد 23378 مشروعًا تشغل حوالي 1.25 تيرابايت من مساحة القرص الثابت.



بالإضافة إلى ذلك ، بالنسبة لكل مشروع ، قمنا بتفريغ قائمة الشوكات ووجدنا أزواج من الشوكات داخل مجموعة البيانات الخاصة بنا - وهذا ضروري لمزيد من التصفية ، نظرًا لأننا لسنا مهتمين بالاستنساخ بين الشوكات. كان هناك 324 مشروعًا في المجموع مع شوكات داخل مجموعة البيانات.



العثور على الحيوانات المستنسخة



للعثور على نسخ ، أي أجزاء متشابهة من التعليمات البرمجية ، تحتاج أيضًا إلى اتخاذ بعض القرارات. أولاً ، نحتاج إلى تحديد مقدار وبأي صفة نحن مهتمون برمز مماثل. تقليديا ، هناك 4 أنواع من الحيوانات المستنسخة (من الأكثر دقة إلى الأقل دقة):



  • النسخ المتطابقة هي نفس أجزاء التعليمات البرمجية التي يمكن أن تختلف فقط في القرارات الأسلوبية ، مثل المسافات البادئة والأسطر الفارغة والتعليقات.
  • تتضمن النسخ المعاد تسميتها النوع الأول ، ولكنها قد تختلف أيضًا في أسماء المتغيرات والكائنات.
  • وثيقة تتضمن استنساخ كل ما سبق، ولكن يمكن أن تحتوي على تغييرات أكثر أهمية، مثل إضافة أو إزالة أو نقل التعبيرات، التي شظايا لا تزال مماثلة.
  • , — , ( ), ().


نحن مهتمون بالنسخ والتعديل ، لذلك نحن نأخذ بعين الاعتبار فقط النسخ من الأنواع الثلاثة الأولى.



القرار الثاني المهم هو حجم المستنسخات التي تبحث عنها. يمكن البحث عن أجزاء الكود المتطابقة بين الملفات ، والفئات ، والأساليب ، والتعبيرات الفردية ... في عملنا ، اتخذنا الطريقة كأساس ، لأن هذه هي دقة البحث الأكثر توازناً: غالبًا ما ينسخ الأشخاص الكود ليس في ملفات كاملة ، ولكن في أجزاء صغيرة ، ولكن في نفس الوقت الطريقة - إنها لا تزال وحدة منطقية كاملة.



استنادًا إلى الحلول المحددة ، للعثور على الحيوانات المستنسخة ، استخدمنا SourcererCC - أداة تبحث عن الحيوانات المستنسخة باستخدام طريقة كيس الكلمات: يتم تمثيل كل طريقة كقائمة تكرار للرموز (الكلمات الرئيسية والأسماء والحرف) ، وبعد ذلك تتم مقارنة هذه المجموعات ، وإذا تزامن أكثر من نسبة معينة من الرموز بطريقتين (تسمى هذه النسبة عتبة التشابه) ، فإن هذا الزوج يعتبر استنساخًا. على الرغم من بساطة هذه الطريقة (هناك طرق أكثر تعقيدًا تعتمد على تحليل أشجار بناء الجملة وحتى الرسوم البيانية للاعتماد على البرامج الخاصة بهم) ، فإن ميزتها الرئيسية هي قابلية التوسع : مع هذا الكم الهائل من التعليمات البرمجية ، مثلنا ، من المهم أن يتم البحث عن الحيوانات المستنسخة بسرعة كبيرة ...



استخدمنا عتبات تشابه مختلفة للعثور على نسخ مختلفة ، وأجرينا أيضًا بحثًا منفصلاً بحد تشابه 100٪ ، حيث تم تحديد النسخ المتطابقة فقط. بالإضافة إلى ذلك ، تم تعيين الحد الأدنى لحجم الطريقة التي تم فحصها لتجاهل الأجزاء التافهة والعامة من التعليمات البرمجية التي قد لا يتم استعارتها.



استغرق هذا البحث ما يصل إلى 66 يومًا من العمليات الحسابية المستمرة ، وتم تحديد 38.6 مليون طريقة ، منها 11.7 مليون فقط تجاوزت الحد الأدنى للحجم ، وشارك 7.6 مليون منها في الاستنساخ. تم العثور على ما مجموعه 1.2 مليار زوج من الحيوانات المستنسخة.



وقت آخر تعديل



لمزيد من التحليل ، اخترنا فقط أزواج من النسخ عبر المشاريع ، أي أزواج من أجزاء الكود المتشابهة الموجودة في مشاريع مختلفة. من وجهة نظر الترخيص ، لسنا مهتمين كثيرًا بأجزاء الكود ضمن نفس المشروع: يُعد تكرار الكود الخاص بك ممارسة سيئة ، لكن هذا غير محظور. في المجموع ، كان هناك حوالي 561 مليون زوج بين المشاريع ، أي ما يقرب من نصف جميع الأزواج. تضمنت هذه الأزواج 3.8 مليون طريقة ، والتي كان من الضروري تحديد وقت التعديل الأخير لها. للقيام بذلك ، تم تطبيق الأمر git blame على كل ملف (والذي تبين أنه 898 ألفًا ، لأنه يمكن أن يكون هناك أكثر من طريقة في الملفات) ، والذي يعرض وقت آخر تعديل لكل سطر في الملف.



إذن لدينا وقت آخر تعديل لكل سطر في الطريقة ، ولكن كيف نحدد وقت آخر تعديل للطريقة بأكملها؟ يبدو الأمر واضحًا - فأنت تأخذ آخر وقت وتستخدمه: بعد كل شيء ، فإنه يظهر حقًا متى تم تغيير الطريقة آخر مرة. ومع ذلك ، بالنسبة لمهمتنا ، فإن هذا التعريف ليس مثاليًا. لنفكر في مثال:





لنفترض أننا وجدنا استنساخًا على شكل جزأين ، كل منهما به 25 سطرًا. يعني اللون الأكثر تشبعًا هنا وقت تعديل لاحق. لنفترض أن الجزء الموجود على اليسار كُتب في وقت ما في عام 2017 ، وفي الجزء الموجود على اليمين تمت كتابة 22 سطرًا في عام 2015 ، وتم تعديل ثلاثة في عام 2019. اتضح أن الجزء الموجود على اليمين تم تعديله لاحقًا ، ولكن إذا أردنا تحديد من يمكنه النسخ من من ، سيكون من المنطقي أكثر أن نفترض العكس: الجزء الأيسر اقترض الجزء الأيمن ، والجزء الأيمن تغير قليلاً فيما بعد. بناءً على ذلك ، حددنا وقت آخر تعديل لجزء من التعليمات البرمجية باعتباره الوقت الأكثر تكرارًا لآخر تعديل على سطوره الفردية. إذا كانت هناك عدة مرات فجأة ، تم اختيار واحدة لاحقة.



ومن المثير للاهتمام ، أن أقدم جزء من التعليمات البرمجية في مجموعة البيانات الخاصة بنا تمت كتابته في أبريل 1997 ، في فجر جافا ، ووجد استنساخًا تم إنشاؤه في عام 2019!



تحديد التراخيص



الخطوة الثانية والأكثر أهمية هي تحديد الترخيص لكل قطعة. لهذا ، استخدمنا المخطط التالي. بادئ ذي بدء ، باستخدام أداة Ninka ، تم تحديد الترخيص المحدد مباشرة في رأس الملف. إذا كان هناك واحد ، فإنه يعتبر ترخيصًا لكل طريقة فيه (Ninka قادرة على التعرف على عدة تراخيص في نفس الوقت). إذا لم يتم تحديد أي شيء في الملف ، أو إذا كانت المعلومات غير كافية (على سبيل المثال ، حقوق النشر فقط) ، فسيتم استخدام ترخيص المشروع بأكمله الذي ينتمي إليه الملف. تم احتواء البيانات المتعلقة به في أرشيف Git الأصلي ، والذي على أساسه جمعنا مجموعة البيانات ، وتم تحديده باستخدام أداة أخرى - Go License Detector . إذا لم يكن الترخيص موجودًا في الملف أو في المشروع ، فسيتم تمييز هذه الطرق على أنهاGitHub ، حيث يخضعون بعد ذلك لشروط خدمة GitHub (حيث تم تنزيل جميع بياناتنا).



بعد تحديد جميع التراخيص بهذه الطريقة ، يمكننا أخيرًا الإجابة عن السؤال حول التراخيص الأكثر شيوعًا. وجدنا 94 ترخيصًا مختلفًا في المجموع . نحن نقدم إحصائيات للملفات هنا للتعويض عن مكامن الخلل المحتملة بسبب الملفات الكبيرة جدًا مع الكثير من الأساليب.



السمة الرئيسية لهذا الجدول هي أقوى توزيع غير متكافئ للتراخيص. يمكن رؤية ثلاثة مجالات في الرسم البياني: اثنان "ترخيصان" مع أكثر من 100 ألف ملف ، وعشرة أخرى تحتوي على 10-100 ألف ملف ، وذيل طويل من التراخيص بأقل من 10 آلاف ملف.



لننظر أولاً إلى أكثرها شيوعًا ، حيث نقدم أول منطقتين في مقياس خطي:







يمكن للمرء أن يرى التفاوت حتى بين التراخيص الأكثر شيوعًا. يحتل Apache-2.0 ، وهو الأكثر توازناً من بين جميع التراخيص المسموح بها ، المرتبة الأولى بهامش كبير ؛ فهو يغطي ما يزيد قليلاً عن نصف جميع الملفات.



يتبع ذلك النقص السيئ في الترخيص ، ولا يزال يتعين علينا تحليله بمزيد من التفصيل ، نظرًا لأن هذا الموقف شائع جدًا حتى بين المستودعات المتوسطة والكبيرة (أكثر من 50 نجمة). هذا الظرف مهم جدًا ، لأن مجرد تحميل الكود على GitHub لا يجعله مفتوحًا.- وإذا كان هناك شيء عملي وتحتاج إلى تذكره من هذا المقال ، فهذا هو. بتحميل الرمز الخاص بك على GitHub ، فإنك توافق على شروط الاستخدام ، والتي تنص على أنه يمكن عرض التعليمات البرمجية الخاصة بك وتقسيمها. ومع ذلك ، باستثناء هذا ، تظل جميع حقوق الكود مع المؤلف ، وبالتالي يتطلب التوزيع والتعديل وحتى الاستخدام إذنًا صريحًا. اتضح أنه ليس فقط كل البرامج مفتوحة المصدر خالية تمامًا ، ولا حتى كل التعليمات البرمجية الموجودة على GitHub مفتوحة المصدر بالكامل! ونظرًا لوجود الكثير من هذه الرموز (14٪ من الملفات ، ومن بين المشروعات الأقل شيوعًا التي لم يتم تضمينها في مجموعة البيانات ، على الأرجح أكثر) ، فقد يكون هذا سببًا لعدد كبير من الانتهاكات.



في المراكز الخمسة الأولى ، نرى أيضًا التراخيص المسموح بها من قبل معهد ماساتشوستس للتكنولوجيا (MIT) و BSD ، بالإضافة إلى الحقوق المتروكة GPL-3.0 أو الأحدث. تختلف التراخيص من عائلة GPL ليس فقط في عدد كبير من الإصدارات (ليست سيئة جدًا) ، ولكن أيضًا في التذييل "أو الأحدث" ، والذي يسمح للمستخدم باستخدام شروط هذا الترخيص أو إصداراته الأحدث. هذا يقودنا إلى سؤال آخر: من بين هذه الرخص الـ 94 ، هناك "عائلات" متشابهة بوضوح - أي منها هي الأكبر؟



في المرتبة الثالثة توجد تراخيص GPL - هناك 8 أنواع منها في القائمة. هذه العائلة هي الأكثر أهمية ، لأنها تغطي معًا 12.6٪ من الملفات ، وتأتي في المرتبة الثانية بعد Apache-2.0 وعدم وجود ترخيص. في المرتبة الثانية ، بشكل غير متوقع ، BSD. وإلى جانب التقليدي الإصدار 3 الفقرة وحتى الإصدارات 2 و 4 الفقرة، هناك جداتراخيص محددة - 11 قطعة فقط. وتشمل هذه ، على سبيل المثال ، BSD 3-Clause No ترخيص نووي ، وهو عبارة عن BSD عادي به 3 فقرات ، والذي يُذكر أدناه أنه لا ينبغي استخدام هذا البرنامج لإنشاء أو تشغيل أي شيء نووي:



أنت تقر بأن هذا البرنامج غير مصمم ، مرخصة أو مخصصة للاستخدام في تصميم أو إنشاء أو تشغيل أو صيانة أي منشأة نووية.



الأكثر تنوعًا هي مجموعة تراخيص المشاع الإبداعي ، والتي يمكنك أن تقرأ عنها هنا . كان هناك ما يصل إلى 13 منهم ، وهم أيضًا يستحقون على الأقل تصفحهم لسبب واحد مهم: كل الكود على StackOverflow مرخص بموجب CC-BY-SA.



من بين التراخيص النادرة ، هناك بعض التراخيص البارزة ، على سبيل المثال ،Do What The F * ck You Want To Public License (WTFPL) ، والتي تغطي 529 ملفًا وتتيح لك القيام بالضبط بما يقوله الاسم مع الكود. هناك أيضًا ، على سبيل المثال ، ترخيص Beerware ، والذي يسمح لك أيضًا بفعل أي شيء ويشجع المؤلف على شراء بيرة في الاجتماع. في مجموعة البيانات الخاصة بنا ، صادفنا أيضًا مجموعة متنوعة من هذا الترخيص ، والتي لم نعثر عليها في أي مكان آخر - ترخيص Sushiware . وبناء على ذلك ، فإنها تشجع صاحب البلاغ على شراء السوشي.



هناك موقف غريب آخر عندما يتم العثور على عدة تراخيص في ملف واحد (تحديدًا في الملف). في مجموعة البيانات الخاصة بنا ، يوجد 0.9٪ فقط من هذه الملفات. يتم تغطية 7.4 ألف ملف بواسطة ترخيصين في وقت واحد ، وتم العثور على إجمالي 74 زوجًا مختلفًا من هذه التراخيص. 419 ملفًا مغطاة بثلاثة تراخيص ، وهناك ثمانية من هذه التراخيص. وأخيرًا ،يشير ملف واحد في مجموعة البيانات الخاصة بنا إلى أربعة تراخيص مختلفة في العنوان.



قروض محتملة



الآن بعد أن تحدثنا عن التراخيص ، يمكننا مناقشة العلاقة بينهما. أول شيء يجب فعله هو إزالة الحيوانات المستنسخة التي لا يمكن أن تكون قروضًا . دعني أذكرك أنه في الوقت الحالي حاولنا أن نأخذ ذلك في الاعتبار بطريقتين - الحد الأدنى لحجم أجزاء الكود واستبعاد النسخ داخل مشروع واحد. سنقوم الآن بتصفية ثلاثة أنواع أخرى من الأزواج:



  • لسنا مهتمين بالأزواج بين الشوكة والأصل (وكذلك ، على سبيل المثال ، بين شوكتين من نفس المشروع) - لهذا قمنا بجمعها.
  • كما أننا لسنا مهتمين بالاستنساخ بين المشاريع المختلفة التي تنتمي إلى نفس المنظمة أو المستخدم (لأننا نفترض أن حقوق النشر مشتركة داخل نفس المنظمة).
  • أخيرًا ، من خلال التحقق يدويًا من عدد كبير بشكل غير طبيعي من الحيوانات المستنسخة بين مشروعين ، وجدنا مرايا مهمة (وهي أيضًا شوكات غير مباشرة) ، أي مشاريع متطابقة تم تحميلها إلى مستودعات غير ذات صلة.


من الغريب أن ما يصل إلى 11.7٪ من الأزواج المتبقية هي نسخ متطابقة مع حد تشابه 100٪ - ربما يبدو بديهيًا أنه يجب أن يكون هناك كود أقل تطابقًا تمامًا على GitHub.



نقوم بمعالجة جميع الأزواج المتبقية بعد هذا التصفية على النحو التالي:



  1. قارنا وقت التعديل الأخير لطريقتين في الزوج.
  2. , : .
  3. , «» «» . , 2015 MIT, 2018 — Apache-2.0, MIT → Apache-2.0.


في النهاية ، لخصنا عدد الأزواج لكل اقتراض محتمل وقمنا بفرزها بترتيب تنازلي:







هنا التبعية أكثر تطرفًا: احتمال استعارة كود داخل حسابات Apache-2.0 لأكثر من نصف جميع أزواج النسخ ، وتغطي أول 10 أزواج من التراخيص بالفعل أكثر من 80٪ من النسخ. من المهم أيضًا ملاحظة أن الزوجين الثاني والثالث الأكثر شيوعًا يتعاملان مع الملفات غير المرخصة - وهي أيضًا نتيجة واضحة لتكرارها. بالنسبة للتراخيص الخمسة الأكثر شيوعًا ، يمكنك عرض الانتقالات كخريطة حرارية:







انتهاكات الترخيص المحتملة



تتمثل الخطوة التالية في بحثنا في تحديد أزواج من الحيوانات المستنسخة التي تمثل انتهاكات محتملة ، أي الاقتراضات التي تنتهك شروط الرخص الأصلية والتراخيص المضيفة. للقيام بذلك ، تحتاج إلى وضع علامة على أزواج التراخيص المذكورة أعلاه على أنها انتقالات مسموح بها أو محظورة . لذلك ، على سبيل المثال ، الانتقال الأكثر شيوعًا ( Apache-2.0 → Apache-2.0 ) هو بالطبع مسموح به ، لكن الانتقال الثاني ( GitHub → Apache-2.0 ) محظور. ولكن يوجد الكثير جدًا ، وهناك الآلاف من هذه الأزواج.



للتعامل مع هذا ، تذكر أن أول 10 أزواج من التراخيص المقدمة تغطي 80٪ من جميع أزواج النسخ. بسبب هذا التفاوت ، اتضح أنه يكفي لتمييز 176 زوجًا فقط من التراخيص يدويًا لتغطية 99٪ من أزواج النسخ ، والتي بدت لنا دقة مقبولة تمامًا. ومن بين هؤلاء الأزواج اعتبرنا أربعة أنواع من الأزواج الممنوعة:



  1. النسخ من ملفات بدون ترخيص (GitHub). كما ذكرنا سابقًا ، يتطلب هذا النسخ إذنًا مباشرًا من مؤلف الكود ، ونفترض أنه ليس كذلك في الغالبية العظمى من الحالات.
  2. يُحظر أيضًا النسخ إلى الملفات بدون ترخيص ، لأن هذا يؤدي في الأساس إلى محو وإزالة التراخيص. تسمح التراخيص المسموح بها مثل Apache-2.0 أو BSD بإعادة استخدام الكود في تراخيص أخرى (بما في ذلك تراخيص الملكية) ، ولكن حتى هذه التراخيص تتطلب الاحتفاظ بالترخيص الأصلي في الملف.
  3. .
  4. (, Apache-2.0 → GPL-2.0).


تم وضع علامة على جميع الأزواج النادرة الأخرى من التراخيص التي تغطي 1٪ من النسخ على أنها متساهلة (حتى لا يتم إلقاء اللوم على أي شخص دون داع) ، باستثناء تلك التي يظهر فيها رمز بدون تراخيص (والتي لا يمكن نسخها أبدًا).



نتيجة لذلك ، بعد رفع السعر ، اتضح أن 72.8٪ من القروض مسموح بها ، و 27.2٪ محظورة. وتظهر الرسوم البيانية التالية الأكثر انتهكت والأكثر مخالفة التراخيص.







على اليسار أكثر التراخيص مخالفة ، أي مصادر أكبر عدد ممكن من الانتهاكات. من بينها ، تحتل الملفات بدون تراخيص المرتبة الأولى ، وهي ملاحظة عملية مهمة - تحتاج إلى مراقبة الملفات عن كثب بشكل خاص بدون تراخيص.... قد يتساءل المرء عما يفعله ترخيص Apache-2.0 المسموح به في هذه القائمة. ومع ذلك ، كما ترون من خريطة التمثيل اللوني أعلاه ، فإن حوالي 25 مليون اقتراض ممنوع منها عبارة عن قروض لملف بدون ترخيص ، وهذا نتيجة لشعبيتها.



على اليمين توجد التراخيص التي يتم نسخها مع الانتهاكات ، وهنا يتم تقديم الأهم من ذلك كله نفس Apache-2.0 و GitHub.



أصل الأساليب الفردية



أخيرًا ، وصلنا إلى النقطة الأخيرة من بحثنا. تحدثنا طوال هذا الوقت عن أزواج من الحيوانات المستنسخة ، كما هو معتاد في مثل هذه الدراسات. ومع ذلك ، فأنت بحاجة إلى فهم نوع معين من أحادية الجانب ، وعدم اكتمال مثل هذه الأحكام. والحقيقة هي أنه إذا كان ، على سبيل المثال ، قطعة واحدة من التعليمات البرمجية بها 20 أخًا "أكبر سنًا" (أو "الآباء" ، من يعلم) ، فسيتم اعتبار جميع الأزواج العشرين قروضًا محتملة. هذا هو السبب في أننا نتحدث عن الاقتراضات "المحتملة" و "المحتملة" - فمن غير المرجح أن مؤلف طريقة معينة استعارها من 20 مكانًا مختلفًا. على الرغم من هذا ، يمكن النظر إلى هذا المنطق على أنه تفكير حول الاستنساخ بين الرخص المختلفة.



لتجنب مثل هذه الأحكام غير المكتملة ، يمكنك النظر إلى نفس الصورة من زاوية مختلفة. صورة الاستنساخ هي في الواقع رسم بياني موجه: جميع الطرق عبارة عن رؤوس عليها ، متصلة بواسطة حواف موجهة من كبير إلى صغير (إذا لم تأخذ في الاعتبار الطرق المؤرخة في نفس اليوم). في القسمين السابقين ، نظرنا إلى هذا الرسم البياني من وجهة نظر الحواف: أخذنا كل حافة ودرسنا رؤوسها (حصلنا على أزواج التراخيص هذه). الآن دعونا ننظر إليها من وجهة نظر الرؤوس. كل قمة (طريقة) على الرسم البياني لها أسلاف (استنساخ "كبار") وأحفاد (استنساخ "صغار"). يمكن أيضًا تقسيم الروابط بينهما إلى "مسموح به" و "ممنوع".



بناءً على ذلك ، يمكن أن تُعزى كل طريقة إلى إحدى الفئات التالية ، والتي تظهر الرسوم البيانية الخاصة بها في الصورة (هنا تشير الخطوط الصلبة إلى الاستعارة المحظورة ، والخطوط المنقطة - مسموح بها):







اثنان من التكوينات المقدمة قد يشكلان انتهاكًا لشروط الترخيص:



  • الانتهاك الجسيم يعني أن الأسلوب له أسلاف وأن جميع الانتقالات منهم ممنوعة. هذا يعني أنه إذا قام المطور بنسخ الكود بالفعل ، فقد فعل ذلك في انتهاك للتراخيص.
  • الانتهاك الضعيف يعني أن للأسلوب أسلاف ، وبعضهم فقط وراء التحولات المحرمة. هذا يعني أن المطور ربما قام بنسخ الكود في انتهاك للترخيص.


التكوينات الأخرى ليست انتهاكات:



  • , , .
  • — , — , .
  • , , — , . , , — , . : , , , , ( , , ).


إذن كيف يتم توزيع الأساليب في مجموعة البيانات الخاصة بنا؟







يمكنك أن ترى أن حوالي ثلث الطرق لا تحتوي على نسخ على الإطلاق ، وثلثًا آخر له نسخ فقط في المشاريع المرتبطة. من ناحية أخرى ، فإن 5.4٪ من الأساليب تمثل "مخالفة خفيفة" و 4٪ "مخالفة جسيمة". على الرغم من أن هذه الأرقام قد لا تبدو كبيرة جدًا ، إلا أنه لا يزال هناك مئات الآلاف من الأساليب في أكثر أو أقل من المشاريع الكبيرة.



TL ؛ DR



بالنظر إلى أن هذه المقالة تحتوي على الكثير من الأشكال والرسوم البيانية التجريبية ، فلنكرر نتائجنا الرئيسية:



  • الطرق التي لها عدد المستنسخات بالملايين ، وهناك أكثر من مليار زوج بينها.
  • , Java- 50 , 94 , : Apache-2.0 . Apache-2.0 .
  • , 27,2%, .
  • 35,4% , 5,4% «» , 4% «» .


?



في الختام ، أود أن أتحدث عن سبب الحاجة إلى كل ما سبق على الإطلاق. لدي ثلاث إجابات على الأقل.



أولاً ، إنه مثير للاهتمام . الترخيص متنوع مثل جميع جوانب البرمجة الأخرى. قائمة التراخيص بحد ذاتها مثيرة للفضول بسبب خصوصية وندرة بعض التراخيص ، فالناس يكتبونها ويعملون معها بطرق مختلفة. ينطبق هذا أيضًا بلا شك على النسخ الموجودة في الكود وتشابه الكود بشكل عام. توجد طرق بها آلاف النسخ ، وهناك طرق بدون طريقة واحدة ، بينما في لمحة سريعة ليس من السهل دائمًا ملاحظة الاختلاف الأساسي بينهما.



ثانيًا ، يسمح لنا التحليل التفصيلي لنتائجنا بصياغة عدة نصائح عملية :



  1. - . Apache-2.0, MIT, BSD-3-Clause, GPL LGPL.
  2. : . - , , .
  3. GitHub, . . — , . : - , , , , . , .


للحصول على أوصاف واضحة للتراخيص ، بالإضافة إلى النصائح حول اختيار ترخيص لمشروعك الجديد ، يمكنك اللجوء إلى خدمات مثل tldrlegal أو ترخيص الاختيار .



أخيرًا ، يمكن استخدام البيانات التي تم الحصول عليها لإنشاء الأدوات . في الوقت الحالي ، يعمل زملاؤنا على تطوير طريقة لتحديد التراخيص بسرعة باستخدام أساليب التعلم الآلي (والتي تحتاج فقط إلى الكثير من التراخيص المحددة) ومكون IDE الإضافي الذي سيسمح للمطورين بتتبع التبعيات في مشاريعهم وملاحظة حالات عدم التوافق المحتملة مسبقًا.



نأمل أن تكون قد تعلمت شيئًا جديدًا من هذه المقالة. الامتثال لشروط الترخيص الأساسية ليس مرهقًا للغاية ، ويمكنك القيام بكل شيء وفقًا للقواعد بأقل جهد ممكن. فلنثقف الآخرين ونثقفهم ونقترب أكثر من حلم البرمجيات مفتوحة المصدر "الصحيحة" معًا!



All Articles