A megoldásszintű --output beállítás már nem érvényes a buildel kapcsolatos parancsokra

A 7.0.200 SDK-ban módosult, hogy a következő parancsokkal rendelkező megoldásfájl használatakor már nem fogadható el a --output/-o beállítás:

  • build
  • clean
  • pack
  • publish
  • store
  • test
  • vstest

Ennek az az oka, hogy a lehetőség által --output/-o szabályozott tulajdonság szemantikája OutputPath nem definiált jól a megoldásokhoz. Az így létrehozott projektek kimenete ugyanabban a könyvtárban lesz elhelyezve, ami inkonzisztens, és számos felhasználó által jelentett problémát eredményezett.

Ez a módosítás a 7.0.201 SDK-ban figyelmeztetési szintűre csökkent, és pack az érintett parancsok listájáról el lett távolítva.

Bevezetett verzió

.NET 7.0.200 SDK, csak a 7.0.201 SDK-ban figyelmeztetésre csökkentve.

Előző viselkedés

Korábban, ha a megoldásfájl használatakor adta meg --output/-o , az összes beépített projekt kimenete meghatározatlan és inkonzisztens sorrendben lesz elhelyezve a megadott könyvtárban.

Új viselkedés

A dotnet parancssori felület hibaüzenetet ad, ha a --output/-o megoldást egy megoldásfájllal használja. A 7.0.201 SDK-tól kezdve a rendszer figyelmeztetést ad ki, és dotnet pack nem jön létre figyelmeztetés vagy hiba.

A kompatibilitástörő változás típusa

Ez a kompatibilitástörő változás a szkriptek és a folyamatos integrációs folyamatok létrehozásához módosításokat igényelhet. Emiatt a bináris és a forráskompatibilitást is befolyásolja.

A változás oka

Ez a módosítás azért történt, mert a tulajdonság szemantikája OutputPath , amelyet a --output/-o lehetőség vezérel, nem definiált jól a megoldásokhoz. Az így létrehozott projektek kimenete ugyanabban a könyvtárban lesz elhelyezve, ami inkonzisztens, és számos felhasználó által jelentett problémát eredményezett.

Ha egy megoldás ezzel a --output beállítással van létrehozva, a OutputPath tulajdonság minden projekt esetében azonos értékre van állítva, ami azt jelenti, hogy minden projekt kimenete ugyanabban a könyvtárban lesz elhelyezve. A megoldásban lévő projektek összetettségétől függően eltérő és inkonzisztens eredmények fordulhatnak elő. Tekintsünk meg néhány példát a különböző megoldásalakzatokra, és arra, hogy a megosztott OutputPathalakzatok hogyan érintik őket.

Egyetlen projekt, egyetlen TargetFramework

Képzeljen el egy olyan megoldást, amely egyetlen projektet TargetFrameworktartalmaz egyetlen , net7.0. Ebben az esetben a --output beállítás megadása egyenértékű a OutputPath projektfájl tulajdonságának beállításával. A buildelés során (vagy más parancsok, de most nézzük meg a buildeléshez szükséges vitafórumot) a projekt összes kimenete a megadott könyvtárba kerül.

Egy projekt, több TargetFrameworks

Most képzeljen el egy megoldást, amely egyetlen projektet tartalmaz több TargetFrameworks, net6.0 és net7.0. A több célzás miatt a projekt kétszer lesz felépítve, mindegyikhez TargetFrameworkegyszer. Az egyes "belső" buildek esetében a OutputPath rendszer ugyanazt az értéket állítja be, így az egyes belső buildek kimenetei ugyanabba a könyvtárba kerülnek. Ez azt jelenti, hogy bármelyik build is fejeződik be utoljára, felülírja a másik build kimenetét, és az olyan párhuzamos buildelési rendszerekben, mint az MSBuild, alapértelmezés szerint működik, az "utolsó" határozatlan.

Library => Console => Test, single TargetFramework

Most képzeljen el egy megoldást, amely tartalmaz egy erőforrástárprojektet, egy konzolprojektet, amely a tárprojektre hivatkozik, és egy tesztprojektet, amely a konzolprojektre hivatkozik. Ezek a projektek egyetlen TargetFramework, net7.0. Ebben az esetben először a kódtárprojekt lesz felépítve, majd a konzolprojekt. A tesztprojekt utoljára készül el, és a konzolprojektre fog hivatkozni. Minden egyes beépített projekt esetében az egyes buildek kimenetei a megadott könyvtárba OutputPathlesznek másolva, így a végső könyvtár mindhárom projektből származó objektumokat tartalmaz. Ez tesztelésre használható, de közzététel esetén előfordulhat, hogy a teszteszközöket éles környezetbe küldik.

Library => Console => Test, multiple TargetFrameworks

Most vegyük ugyanazt a projektláncot, és a build mellett egy net6.0TargetFramework buildet is hozzáadunk hozzájuk net7.0 . Ugyanaz a probléma, mint az egyprojektes, több célzott build – a TFM-specifikus objektumok inkonzisztens másolása a megadott könyvtárba.

Több alkalmazás

Eddig lineáris függőségi gráfokkal rendelkező forgatókönyveket néztünk meg, de számos megoldás több kapcsolódó alkalmazást is tartalmazhat. Ez azt jelenti, hogy egyszerre több alkalmazás is készülhet ugyanarra a kimeneti mappára. Ha az alkalmazások azonos nevű függőségfájlt tartalmaznak, akkor előfordulhat, hogy a build időnként meghiúsul, amikor több projekt próbál meg egyszerre írni a fájlba a kimeneti útvonalon.

Ha egy fájl különböző verzióitól több alkalmazás is függ, akkor még akkor is, ha a build sikeres, akkor is előfordulhat, hogy a fájl melyik verzióját másolja a kimeneti útvonalra. Ez akkor fordulhat elő, ha a projektek (esetleg tranzitív módon) a NuGet-csomagok különböző verzióitól függenek. Egyetlen projekten belül a NuGet biztosítja, hogy a függőségei (beleértve a NuGet-csomagokon és/vagy projekthivatkozásokon keresztüli tranzitív függőségeket) egységesek legyenek ugyanahhoz a verzióhoz. Mivel az egyesítés egyetlen projekt és annak függő projektjei kontextusában történik, ez azt jelenti, hogy a csomag különböző verzióit fel lehet oldani két különálló legfelső szintű projekt létrehozásakor. Ha a magasabb verziótól függő projekt utoljára másolja a függőséget, akkor az alkalmazások gyakran sikeresen futnak. Ha azonban az alacsonyabb verziót másolja utoljára, akkor a magasabb verzióra lefordított alkalmazás futásidőben nem fogja betölteni a szerelvényt. Mivel a másolt verzió nem determinisztikus lehet, ez szórványos, megbízhatatlan buildekhez vezethet, ahol nagyon nehéz diagnosztizálni a problémát.

Más példák

Az alapul szolgáló hiba gyakorlati bemutatására további példákat a dotnet/sdk#15607 című cikkben talál.

Az általános javaslat az, hogy a korábban a beállítás nélkül-o/--output végrehajtott műveletet hajtsa végre, majd a parancs befejezése után helyezze át a kimenetet a kívánt helyre. A műveletet egy adott projektben is végrehajthatja, és továbbra is alkalmazhatja a --output/-o lehetőséget, mivel az jobban definiált szemantikával rendelkezik.

Ha pontosan szeretné fenntartani a meglévő viselkedést, akkor a --property jelölővel beállíthatja az MSBuild tulajdonságot a kívánt könyvtárra. A használni kívánt tulajdonság a parancstól függően változik:

Parancs Tulajdonság Példa
build OutputPath dotnet build --property:OutputPath=DESIRED_PATH
clean OutputPath dotnet clean --property:OutputPath=DESIRED_PATH
pack PackageOutputPath dotnet pack --property:PackageOutputPath=DESIRED_PATH
publish PublishDir dotnet publish --property:PublishDir=DESIRED_PATH
store OutputPath dotnet store --property:OutputPath=DESIRED_PATH
test TestResultsDirectory dotnet test --property:OutputPath=DESIRED_PATH

MEGJEGYZÉS A legjobb eredmény érdekében a DESIRED_PATH abszolút elérési útnak kell lennie. A relatív elérési utak "rögzítettek" lesznek (vagyis abszolútak), olyan módon, ahogyan nem várható, és nem minden parancs esetében ugyanúgy működnek.