أداة قرار التبعية
محلل التبعية (يشار إليه فيما يلي باسم حلال ، الترجمة تقريبًا.) أو مدير الحزم هو برنامج يحدد مجموعة متسقة من الوحدات النمطية مع مراعاة القيود التي وضعها المستخدم.
عادة ما يتم تحديد القيود بواسطة أسماء الوحدات النمطية وأرقام الإصدار. في النظام البيئي JVM لوحدات Maven ، سيتم الإشارة أيضًا إلى اسم المنظمة (معرف المجموعة). بالإضافة إلى ذلك ، قد تشمل القيود نطاقات الإصدار والوحدات النمطية المستبعدة وتجاوزات الإصدار وما إلى ذلك.
يتم تمثيل الفئات الثلاث الرئيسية للحزم بواسطة حزم OS (Homebrew ، حزم Debian ، إلخ) ،
الوحدات النمطية الخاصة بلغات البرمجة المحددة (CPAN ، و RubyGem ، و Maven ، إلخ) والإضافات الخاصة بالتطبيق (الإضافات Eclipse ، والإضافات IntelliJ ، وملحقات VS Code).
دلالات محلل
في التقريب الأول ، يمكننا تمثيل تبعيات الوحدات كوحدة رسم بيانية (رسم بياني موجه موجه ، رسم بياني موجه).
يسمى هذا التمثيل الرسم البياني التبعية. النظر في التبعيات من وحدتين:
a:1.0
يعتمد على c:1.0
b:1.0
يعتمد على c:1.0
و d:1.0
+-----+ +-----+ |a:1.0| |b:1.0| +--+--+ +--+--+ | | +<-------+ | | vv +--+--+ +--+--+ |c:1.0| |d:1.0| +-----+ +-----+
إذا كانت الوحدة النمطية تعتمد على a:1.0
و b:1.0
، فسيتم تقديم قائمة كاملة من التبعيات a:1.0
و b:1.0
و c:1.0
و d:1.0
. وهذه مجرد جولة شجرة.
سيصبح الموقف أكثر تعقيدًا إذا تم تحديد التبعيات متعدية بواسطة مجموعة من الإصدارات:
a:1.0
يعتمد على c:1.0
b:1.0
يعتمد على c:[1.0,2)
و d:1.0
+-----+ +-----+ |a:1.0| |b:1.0| +--+--+ +--+--+ | | | +-----------+ | | | vvv +--+--+ +--+------+ +--+--+ |c:1.0| |c:[1.0,2)| |d:1.0| +-----+ +---------+ +-----+
أو ، إذا تم تحديد إصدارات مختلفة للتبعيات متعدية:
a:1.0
يعتمد على c:1.0
b:1.0
يعتمد على c:1.2
و d:1.2
أو إذا تم طرح استثناءات على التبعية:
- الاعتماد على
a:1.0
، والذي يعتمد على c:1.0
، باستثناء c:*
b:1.0
يعتمد على c:1.2
و d:1.2
تقوم أدوات تحليل مختلفة بتفسير القيود التي وضعها المستخدمون بشكل مختلف. أنا أسمي مثل هذه القواعد دلالات الحل.
قد تحتاج إلى معرفة بعض هذه الدلالات ، على سبيل المثال:
- دلالات الوحدة النمطية الخاصة بك (التي تحددها أداة البناء التي تستخدمها) ؛
- دلالات المكتبات التي تستخدمها (تحددها أداة البناء التي استخدمها المؤلف) ؛
- دلالات الوحدات النمطية التي ستستخدمها الوحدة النمطية الخاصة بك تبعية (المعرّفة من قِبل أداة إنشاء المستخدم النهائي).
أدوات حل التبعية في JVM Ecosystem
منذ أن أؤيد sbt
، لا بد لي من العمل في المقام الأول في النظام البيئي JVM.
دلالات مافن: الأقرب يفوز
في الرسوم البيانية حيث يوجد تعارض في التبعيات (في الرسم البياني للاعتماد a
هناك العديد من الإصدارات المختلفة من المكون d
، على سبيل المثال d:1.0
و d:2.0
) ، يستخدم Maven إستراتيجية الأقرب للفوز لحل التعارض.
حل تعارضات التبعية هي عملية تحدد أي إصدار من قطعة أثرية سيتم تحديده إذا تم العثور على عدة إصدارات مختلفة من نفس الأداة بين التبعيات. Maven يختار أقرب تعريف. أي يستخدم الإصدار الأقرب إلى مشروعك في شجرة التبعية.
يمكنك دائمًا ضمان استخدام الإصدار الصحيح من خلال الإعلان صراحةً في POM للمشروع. لاحظ أنه إذا كان لإصدارين من التبعية نفس العمق في الشجرة ، فسيتم تحديد الإصدار الأول. أقرب تعريف يعني أنه سيتم استخدام الإصدار الأقرب إلى المشروع في شجرة التبعية. على سبيل المثال ، إذا تم تعريف التبعيات A
و B
و C
أنها A -> B -> C -> D 2.0
و A -> E -> D 1.0
، عندئذٍ ، عند استخدام المبنى A
، سيتم استخدام D 1.0
، لأن المسار من A
إلى D
عبر E
أقصر (من خلال B
و C
، تقريبًا الترجمة.).
هذا يعني أن العديد من وحدات Java المنشورة باستخدام Maven تم تجميعها باستخدام دلالات nearest-wins
. لتوضيح ما سبق ، قم بإنشاء pom.xml
بسيط:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>foo</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>com.typesafe.play</groupId> <artifactId>play-ws-standalone_2.12</artifactId> <version>1.0.1</version> </dependency> </dependencies> </dependencyManagement> </project>
mvn dependency:build-classpath
بإرجاع classpath
حلها.
من الجدير بالذكر أن الشجرة الناتجة تستخدم com.typesafe:config:1.2.0
على الرغم من أن Akka 2.5.3
يعتمد بشكل com.typesafe:config:1.3.1
على com.typesafe:config:1.3.1
.
mvn dependency:tree
يعطي هذا التأكيد البصري:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ foo --- [INFO] com.example:foo:jar:1.0.0 [INFO] \- com.typesafe.play:play-ws-standalone_2.12:jar:1.0.1:compile [INFO] +- org.scala-lang:scala-library:jar:2.12.2:compile [INFO] +- javax.inject:javax.inject:jar:1:compile [INFO] +- com.typesafe:ssl-config-core_2.12:jar:0.2.2:compile [INFO] | +- com.typesafe:config:jar:1.2.0:compile [INFO] | \- org.scala-lang.modules:scala-parser-combinators_2.12:jar:1.0.4:compile [INFO] \- com.typesafe.akka:akka-stream_2.12:jar:2.5.3:compile [INFO] +- com.typesafe.akka:akka-actor_2.12:jar:2.5.3:compile [INFO] | \- org.scala-lang.modules:scala-java8-compat_2.12:jar:0.8.0:compile [INFO] \- org.reactivestreams:reactive-streams:jar:1.0.0:compile
توفر العديد من المكتبات التوافق مع الإصدارات السابقة ، لكن التوافق المباشر غير مضمون مع وجود بعض الاستثناءات القليلة ، وهو أمر مقلق.
دلالات أباتشي اللبلاب: آخر انتصارات
بشكل افتراضي ، يستخدم Apache Ivy إستراتيجية الأحدث فوزًا لحل تعارضات التبعية.
إذا لم تكن هذه الحاوية موجودة ، فسيتم استخدام مدير التعارض الافتراضي لجميع الوحدات. مدير التعارض الافتراضي الحالي هو "المراجعة الأخيرة".
ملاحظة: conflicts
الحاوية هو أحد ملفات Ivy.
حتى إصدار SBT 1.3.x
محلل التبعية الداخلية هو Apache Ivy. pom.xml
المستخدم سابقًا في SBT لفترة وجيزة:
ThisBuild / scalaVersion := "2.12.8" ThisBuild / organization := "com.example" ThisBuild / version := "1.0.0-SNAPSHOT" lazy val root = (project in file(".")) .settings( name := "foo", libraryDependencies += "com.typesafe.play" %% "play-ws-standalone" % "1.0.1", )
في sbt shell
أدخل show externalDependencyClasspath
للحصول على classpath الذي تم حله. يجب أن تشير إلى إصدار com.typesafe:config:1.3.1
. بالإضافة إلى ذلك ، سيظل التحذير التالي معروضًا:
[warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.
يتيح لك استدعاء evicted
الذي تم sbt shell
الحصول على تقرير حول حل النزاع:
sbt:foo> evicted [info] Updating ... [info] Done updating. [info] Here are other dependency conflicts that were resolved: [info] * com.typesafe:config:1.3.1 is selected over 1.2.0 [info] +- com.typesafe.akka:akka-actor_2.12:2.5.3 (depends on 1.3.1) [info] +- com.typesafe:ssl-config-core_2.12:0.2.2 (depends on 1.2.0) [info] * com.typesafe:ssl-config-core_2.12:0.2.2 is selected over 0.2.1 [info] +- com.typesafe.play:play-ws-standalone_2.12:1.0.1 (depends on 0.2.2) [info] +- com.typesafe.akka:akka-stream_2.12:2.5.3 (depends on 0.2.1)
في دلالات latest-wins
، يعني تحديد config:1.2.0
في الممارسة "توفر لي الإصدار 1.2.0 أو أعلى."
هذا السلوك أفضل قليلاً مما كان عليه في استراتيجية nearest-wins
، لأنه لم يتم تقليل إصدارات المكتبات متعدية. ومع ذلك ، يجب أن تحقق المكالمة التي evicted
لمعرفة ما إذا كانت البدائل قد تم إجراؤها بشكل صحيح.
الدلالات Coursier: أحدث انتصارات
قبل أن نقترب من وصف الدلالات ، سأجيب على سؤال مهم - كيف يتم توضيح كورسييه. وفقا لملاحظة أليكس أرشامبو ، هو واضح كتكوت .
ومن المثير للاهتمام ، أن وثائق Coursier تحتوي على صفحة حول الإصدار ، تتحدث عن دلالات حل التبعيات.
النظر في تقاطع فترات معينة:
- إذا كان فارغًا (لا تتقاطع الفواصل الزمنية) ، فهناك تعارض.
- إذا لم يتم تحديد فواصل زمنية ، فيُفترض أن التقاطع يمثله (،) (الفاصل الزمني المقابل لجميع الإصدارات).
بعد ذلك ، ضع في اعتبارك إصدارات محددة:
- نحن نتجاهل إصدارات محددة أسفل حدود الفاصل الزمني.
- إذا كانت هناك إصدارات محددة أعلى من حدود الفاصل الزمني ، فهناك تعارض.
- إذا كانت هناك إصدارات محددة داخل حدود الفاصل الزمني ، فيجب أن تكون النتيجة هي الأحدث منها.
- إذا لم تكن هناك إصدارات محددة داخل حدود الفاصل الزمني أو أعلى منه ، فيجب أن تكون النتيجة هي الفاصل الزمني.
لأن يقال
، لذلك - وهذا هو دلالات latest-wins
.
يمكنك التحقق من ذلك من خلال اتخاذ sbt 1.3.0-RC3
، والذي يستخدم Coursier.
ThisBuild / scalaVersion := "2.12.8" ThisBuild / organization := "com.example" ThisBuild / version := "1.0.0-SNAPSHOT" lazy val root = (project in file(".")) .settings( name := "foo", libraryDependencies += "com.typesafe.play" %% "play-ws-standalone" % "1.0.1", )
استدعاء show externalDependencyClasspath
من وحدة التحكم sbt 1.3.0-RC3
سيعود com.typesafe:config:1.3.1
، كما هو متوقع. تقرير حل النزاعات تقرير نفسه:
sbt:foo> evicted [info] Here are other dependency conflicts that were resolved: [info] * com.typesafe:config:1.3.1 is selected over 1.2.0 [info] +- com.typesafe.akka:akka-actor_2.12:2.5.3 (depends on 1.3.1) [info] +- com.typesafe:ssl-config-core_2.12:0.2.2 (depends on 1.2.0) [info] * com.typesafe:ssl-config-core_2.12:0.2.2 is selected over 0.2.1 [info] +- com.typesafe.play:play-ws-standalone_2.12:1.0.1 (depends on 0.2.2) [info] +- com.typesafe.akka:akka-stream_2.12:2.5.3 (depends on 0.2.1)
ملاحظة: أباتشي آيفي يحاكي دلالات nearest-wins
؟
عند حل تبعيات الوحدة النمطية من مستودع Maven ، يحول Ivy ملف POM
ويضع السمة force="true"
في ivy.xml
في ذاكرة التخزين المؤقت.
على سبيل المثال ، cat ~/.ivy2/cache/com.typesafe.akka/akka-actor_2.12/ivy-2.5.3.xml
:
<dependencies> <dependency org="org.scala-lang" name="scala-library" rev="2.12.2" force="true" conf="compile->compile(*),master(compile);runtime->runtime(*)"/> <dependency org="com.typesafe" name="config" rev="1.3.1" force="true" conf="compile->compile(*),master(compile);runtime->runtime(*)"/> <dependency org="org.scala-lang.modules" name="scala-java8-compat_2.12" rev="0.8.0" force="true" conf="compile->compile(*),master(compile);runtime->runtime(*)"/> </dependencies>
الوثائق اللبلاب تقول:
يأخذ هذان المديران الأخيران للصراع في الاعتبار سمة تبعية force
.
وبالتالي ، يمكن أن تعلن التبعيات المباشرة عن سمة force
(انظر التبعية) ، تشير إلى أن التبعية المباشرة والتنقيحات غير المباشرة ، يجب إعطاء الأفضلية لتنقيحات التبعية المباشرة.
بالنسبة لي ، تعني هذه الصيغة أن force="true"
تصميمها من أجل إعادة تعريف منطق latest-wins
ومحاكاة دلالات nearest-wins
الأوزان. ولكن ، لحسن الحظ ، لم يكن من المقرر أن يحدث هذا ، ولدينا الآن latest-wins
: كما نرى ، فإن sbt 1.2.8
يختار com.typesafe:config:1.3.1
.
ومع ذلك ، يمكن للمرء ملاحظة تأثير force="true"
عند استخدام مدير تعارض صارم ، والذي يبدو أنه قد تم كسره.
ThisBuild / conflictManager := ConflictManager.strict
المشكلة هي أن مدير التعارض الصارم لا يبدو أنه يمنع استبدال الإصدار. show externalDependencyClasspath
بإرجاع بمرح com.typesafe:config:1.3.1
.
تتمثل المشكلة ذات الصلة في أن إضافة نسخة من com.typesafe:config:1.3.1
، والتي وضعها مدير تعارض صارم في الرسم البياني ، تؤدي إلى حدوث خطأ.
ThisBuild / scalaVersion := "2.12.8" ThisBuild / organization := "com.example" ThisBuild / version := "1.0.0-SNAPSHOT" ThisBuild / conflictManager := ConflictManager.strict lazy val root = (project in file(".")) .settings( name := "foo", libraryDependencies ++= List( "com.typesafe.play" %% "play-ws-standalone" % "1.0.1", "com.typesafe" % "config" % "1.3.1", ) )
يبدو مثل هذا:
sbt:foo> show externalDependencyClasspath [info] Updating ... [error] com.typesafe#config;1.2.0 (needed by [com.typesafe#ssl-config-core_2.12;0.2.2]) conflicts with com.typesafe#config;1.3.1 (needed by [com.example#foo_2.12;1.0.0-SNAPSHOT]) [error] org.apache.ivy.plugins.conflict.StrictConflictException: com.typesafe#config;1.2.0 (needed by [com.typesafe#ssl-config-core_2.12;0.2.2]) conflicts with com.typesafe#config;1.3.1 (needed by [com.example#foo_2.12;1.0.0-SNAPSHOT])
حول الإصدار
ذكرنا latest-wins
دلالات latest-wins
، مما يشير إلى أن الإصدارات في تمثيل سلسلة قد تحدث في بعض الترتيب.
لذلك ، فإن الإصدار هو جزء من الدلالات.
إجراءات الإصدار في Apache Ivy
يقول تعليق Javadoc هذا أنه عند إنشاء مقارنة الإصدارات ، ركز Ivy على وظيفة مقارنة الإصدارات من PHP :
تستبدل هذه الوظيفة أولاً _ و - و + بنقطة .
في تمثيلات سلسلة الإصدارات ويضيف أيضا .
قبل وبعد كل شيء ليس رقما. لذلك ، على سبيل المثال ، يصبح "4.3.2RC1" "4.3.2.RC.1". ثم تقارن الأجزاء المستلمة من اليسار إلى اليمين.
بالنسبة للأجزاء التي تحتوي على عناصر خاصة ( dev
أو alpha
أو a
أو beta
أو b
أو RC
أو rc
أو #
أو pl
أو p
) * ، تتم مقارنة العناصر بالترتيب التالي:
أي سلسلة ليست عنصرًا خاصًا <dev <alpha = a <beta = b <RC = rc <# <pl = p.
وبالتالي ، لا يمكن مقارنة مستويات مختلفة فقط (على سبيل المثال ، "4.1" و "4.1.2") ، ولكن الإصدارات الخاصة بـ PHP تحتوي على معلومات حول حالة التطوير.
* تقريبا. العابرة.
يمكننا التحقق من كيفية ترتيب الإصدارات عن طريق كتابة وظيفة صغيرة.
scala> :paste
إجراءات الإصدار في Coursier
تحتوي صفحة GitHub على دلالات دقة التبعية على قسم حول الإصدار.
يستخدم Coursier ترتيب إصدارات Maven المخصص. قبل المقارنة ، يتم تقسيم تمثيلات السلسلة للإصدارات إلى عناصر منفصلة ...
للحصول على هذه العناصر ، يتم فصل الإصدارات عن طريق الأحرف. و - و _ (ويتم تجاهل الفواصل نفسها) ، وبدائل من حرف إلى رقم أو من رقم إلى حرف.
لكتابة الاختبار ، قم بإنشاء مشروع فرعي باستخدام libraryDependencies += "io.get-coursier" %% "coursier-core" % "2.0.0-RC2-6"
التبعيات libraryDependencies += "io.get-coursier" %% "coursier-core" % "2.0.0-RC2-6"
وتشغيل console
:
sbt:foo> helper/console [info] Starting scala interpreter... Welcome to Scala 2.12.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_212). Type in expressions for evaluation. Or try :help. scala> import coursier.core.Version import coursier.core.Version scala> def sortVersionsCoursier(versions: String*): List[String] = | versions.toList.map(Version.apply).sorted.map(_.repr) sortVersionsCoursier: (versions: String*)List[String] scala> sortVersionsCoursier("1.0", "2.0", "1.0-alpha", "1.0+alpha", "1.0-X1", "1.0a", "2.0.2") res0: List[String] = List(1.0-alpha, 1.0, 1.0-X1, 1.0+alpha, 1.0a, 2.0, 2.0.2)
كما اتضح ، يطلب Coursier أرقام الإصدارات بترتيب مختلف تمامًا عن Ivy.
إذا استخدمت علامات أبجدية متساهلة ، فيمكن لهذا الطلب أن يسبب بعض الالتباس.
حول نطاقات الإصدار
عادةً ما أتجنب استخدام نطاقات الإصدارات ، على الرغم من استخدامها على نطاق واسع في وحدات webjars و npm التي تم إعادة نشرها على Maven Central. يمكن كتابة شيء مثل "is-number": "^4.0.0"
في الوحدة النمطية "is-number": "^4.0.0"
والذي [4.0.0,5)
مع [4.0.0,5)
.
معالجة نطاق الإصدار في Apache Ivy
في هذا التجميع ، angular-boostrap:0.14.2
يعتمد على angular:[1.3.0,)
.
ThisBuild / scalaVersion := "2.12.8" ThisBuild / organization := "com.example" ThisBuild / version := "1.0.0-SNAPSHOT" lazy val root = (project in file(".")) .settings( name := "foo", libraryDependencies ++= List( "org.webjars.bower" % "angular" % "1.4.7", "org.webjars.bower" % "angular-bootstrap" % "0.14.2", ) )
استدعاء show externalDependencyClasspath
في sbt 1.2.8
سيعود angular-bootstrap:0.14.2
angular:1.7.8
. وأين ذهب 1.7.8
؟ عندما يواجه Ivy مجموعة من الإصدارات ، فإنه ينتقل بشكل أساسي إلى الإنترنت ويجد ما يمكنه العثور عليه ، حتى في بعض الأحيان باستخدام نقش الشاشة.
تجعل معالجة نطاقات الإصدار هذه التجميعات غير مكررة (تشغيل التجميع نفسه مرة واحدة كل بضعة أشهر يمنحك نتائج مختلفة).
يتراوح إصدار الإصدار في Coursier
قسم قرار التبعية Coursier على صفحة جيثب
وفيما يلي نصها:
ويفضل إصدارات محددة على فترات
إذا كانت الوحدة النمطية لديك تعتمد على [1.0،2.0) و 1.4 ، فسيتم إجراء الموافقة على الإصدار لصالح 1.4.
إذا كان هناك تبعية على 1.4 ، فسيكون هذا الإصدار مفضلًا في النطاق [1.0،2.0).
يبدو واعدا.
sbt:foo> show externalDependencyClasspath [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings. [info] * Attributed(/Users/eed3si9n/.sbt/boot/scala-2.12.8/lib/scala-library.jar) [info] * Attributed(/Users/eed3si9n/.coursier/cache/v1/https/repo1.maven.org/maven2/org/webjars/bower/angular/1.4.7/angular-1.4.7.jar) [info] * Attributed(/Users/eed3si9n/.coursier/cache/v1/https/repo1.maven.org/maven2/org/webjars/bower/angular-bootstrap/0.14.2/angular-bootstrap-0.14.2.jar)
show externalDependencyClasspath
على نفس التجميع باستخدام angular-bootstrap:0.14.2
تُرجع angular-bootstrap:0.14.2
كما هو متوقع. هذا تحسن على اللبلاب.
خذ بعين الاعتبار الحالة الأكثر تعقيدًا عند استخدام نطاقات إصدار disjoint متعددة. على سبيل المثال:
ThisBuild / scalaVersion := "2.12.8" ThisBuild / organization := "com.example" ThisBuild / version := "1.0.0-SNAPSHOT" lazy val root = (project in file(".")) .settings( name := "foo", libraryDependencies ++= List( "org.webjars.npm" % "randomatic" % "1.1.7", "org.webjars.npm" % "is-odd" % "2.0.0", ) )
استدعاء show externalDependencyClasspath
في sbt 1.3.0-RC3
بإرجاع الخطأ التالي:
sbt:foo> show externalDependencyClasspath [info] Updating https://repo1.maven.org/maven2/org/webjars/npm/kind-of/maven-metadata.xml No new update since 2018-03-10 06:32:27 https://repo1.maven.org/maven2/org/webjars/npm/is-number/maven-metadata.xml No new update since 2018-03-09 15:25:26 https://repo1.maven.org/maven2/org/webjars/npm/is-buffer/maven-metadata.xml No new update since 2018-08-17 14:21:46 [info] Resolved dependencies [error] lmcoursier.internal.shaded.coursier.error.ResolutionError$ConflictingDependencies: Conflicting dependencies: [error] org.webjars.npm:is-number:[3.0.0,4):default(compile) [error] org.webjars.npm:is-number:[4.0.0,5):default(compile) [error] at lmcoursier.internal.shaded.coursier.Resolve$.validate(Resolve.scala:394) [error] at lmcoursier.internal.shaded.coursier.Resolve.validate0$1(Resolve.scala:140) [error] at lmcoursier.internal.shaded.coursier.Resolve.$anonfun$ioWithConflicts0$4(Resolve.scala:184) [error] at lmcoursier.internal.shaded.coursier.util.Task$.$anonfun$flatMap$2(Task.scala:14) [error] at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:307) [error] at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41) [error] at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64) [error] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [error] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [error] at java.lang.Thread.run(Thread.java:748) [error] (update) lmcoursier.internal.shaded.coursier.error.ResolutionError$ConflictingDependencies: Conflicting dependencies: [error] org.webjars.npm:is-number:[3.0.0,4):default(compile) [error] org.webjars.npm:is-number:[4.0.0,5):default(compile)
من الناحية الفنية ، هذا صحيح ، لأنه هذه النطاقات لا تتداخل. بينما sbt 1.2.8
يحل هذا إلى is-number:4.0.0
.
نظرًا لحقيقة أن نطاقات الإصدار شائعة بما فيه الكفاية لتكون مزعجة ، أقوم بإرسال طلب سحب إلى Coursier لتنفيذ قواعد دلالات الأحدث الأحدث التي تسمح لك بتحديد الإصدارات الأحدث من الحدود الدنيا للنطاقات.
انظر coursier / coursier # 1284 .
استنتاج
تعريف دلالات محلل classpath معينة تستند إلى قيود المعرفة من قبل المستخدم.
عادة ، تظهر الاختلافات في التفاصيل بطرق مختلفة لحل تعارضات الإصدار.
- يستخدم Maven إستراتيجية
nearest-wins
، والتي يمكن أن تقلل من التبعيات متعدية. - اللبلاب يستخدم
latest-wins
استراتيجية latest-wins
. - يستخدم Coursier بشكل أساسي استراتيجية
latest-wins
، بينما يحاول تحديد الإصدارات بشكل أكثر صرامة. - ينتقل معالج نطاق إصدار Ivy إلى الإنترنت ، مما يجعل نفس البنية غير قابلة للتكرار.
- يقوم كل من Coursier و Ivy بتنظيم تمثيلات السلسلة للإصدارات بطرق مختلفة جدًا.
لن تتم مناقشة حتى هذه التفاصيل الدقيقة للنظام البيئي Scala في ScalaConf في 26 نوفمبر في موسكو. سيقدم Artem Seleznev ممارسة العمل مع قاعدة البيانات في البرمجة الوظيفية دون JDBC. سوف يتحدث Wojtek Pitula عن التكامل وسيخبر كيف أنشأ تطبيقًا وضع فيه جميع المكتبات العاملة. وسيتم تقديم 16 تقريرا آخر مليئا المتشددين الفني في المؤتمر.