PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
የPVS-Studio analyzerን ለመጠቀም በጣም ወቅታዊ ከሆኑ ሁኔታዎች አንዱ ከ CI ስርዓቶች ጋር ያለው ውህደት ነው። እና ምንም እንኳን የ PVS-Studio ፕሮጀክት ከሞላ ጎደል ከማንኛውም ቀጣይነት ያለው ውህደት ስርዓት ትንታኔ በጥቂት ትዕዛዞች ውስጥ ሊገነባ ቢችልም ይህን ሂደት የበለጠ ምቹ እንዲሆን እናደርጋለን። PVS-ስቱዲዮ አሁን ተንታኝ ውፅዓትን ወደ TeamCity - TeamCity Inspections Type ቅርጸት ለመቀየር ድጋፍ አለው። እንዴት እንደሚሰራ እንይ.

ስለ ጥቅም ላይ የዋለው ሶፍትዌር መረጃ

PVS- ስቱዲዮ - የተለያዩ የስህተት ዓይነቶችን የማግኘት እና የማረም ስራን ለማመቻቸት የተነደፈ የ C ፣ C ++ ፣ C # እና የጃቫ ኮድ የማይንቀሳቀስ ተንታኝ ። ተንታኙ በዊንዶውስ ፣ ሊኑክስ እና ማክኦኤስ ላይ ሊያገለግል ይችላል። በዚህ ጽሑፍ ውስጥ ትንታኔውን እራሱን ብቻ ሳይሆን አንዳንድ መገልገያዎችን ከስርጭቱ ውስጥ በንቃት እንጠቀማለን ።

CLMonitor - የማጠናከሪያ ጅምርን የሚቆጣጠር የክትትል አገልጋይ ነው። ፕሮጀክትዎን ለመገንባት ከመጀመርዎ በፊት ወዲያውኑ መከናወን አለበት። በማሸለብ ሁነታ፣ አገልጋዩ የሁሉንም የሚደገፉ የማጠናቀቂያ ስራዎችን ያቋርጣል። ይህ መገልገያ የC/C++ ፕሮጀክቶችን ለመተንተን ብቻ ጥቅም ላይ ሊውል እንደሚችል ልብ ሊባል የሚገባው ጉዳይ ነው።

PlogConverter - ተንታኝ ሪፖርቶችን ወደ ተለያዩ ቅርጸቶች ለመቀየር መገልገያ።

በጥናት ላይ ስላለው ፕሮጀክት መረጃ

ይህንን ተግባር በተግባራዊ ምሳሌ እንሞክር - የ OpenRCT2 ፕሮጀክትን እንመርምር።

ክፈትRCT2 - የጨዋታውን የ RollerCoaster Tycoon 2 (RCT2) ክፍት ትግበራ ፣ በአዲስ ተግባራት በማስፋት እና ሳንካዎችን በማስተካከል። የጨዋታ ጨዋታ ጉዞዎችን፣ ሱቆችን እና መገልገያዎችን የያዘ የመዝናኛ ፓርክ በመገንባት እና በመንከባከብ ላይ ያተኩራል። ተጫዋቹ ትርፍ ለማግኘት እና የፓርኩን መልካም ስም ለማስጠበቅ እና እንግዶችን በማስደሰት መሞከር አለበት። OpenRCT2 በሁለቱም ሁኔታዎች እና ማጠሪያ ውስጥ እንዲጫወቱ ይፈቅድልዎታል። ሁኔታዎች ተጫዋቹ በተወሰነ ጊዜ ውስጥ አንድን የተወሰነ ተግባር እንዲያጠናቅቅ ይጠይቃሉ ፣ Sandbox ግን ተጫዋቹ ያለ ምንም ገደብ እና ፋይናንስ የበለጠ ተለዋዋጭ ፓርክ እንዲገነባ ያስችለዋል።

በደንብ ማድረግ

ጊዜን ለመቆጠብ ምናልባት የመጫን ሂደቱን ልዘልለው እና የ TeamCity አገልጋይ በኮምፒውተሬ ላይ ከሰራሁበት ጊዜ ጀምሮ እጀምራለሁ. ወደ፡ localhost፡{በመጫን ሂደት ውስጥ የተገለጸውን ወደብ} (በእኔ ሁኔታ localhost:9090) መሄድ እና የፈቀዳ ውሂብ ማስገባት አለብን። ከገባን በኋላ ሰላምታ ይሰጠናል፡-

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
የፕሮጀክት ፍጠር ቁልፍን ጠቅ ያድርጉ። በመቀጠል በእጅ ይምረጡ እና መስኮቹን ይሙሉ።

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
አዝራሩን ከተጫኑ በኋላ ፈጠረ, ቅንጅቶች ባለው መስኮት እንቀበላለን.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
ጠቅ እናድርግ የግንባታ ውቅር ይፍጠሩ.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
መስኮቹን ይሙሉ እና ጠቅ ያድርጉ ፈጠረ. የስሪት መቆጣጠሪያ ስርዓት እንድትመርጥ የሚጠይቅ መስኮት እናያለን። ምንጮቹ ቀድሞውኑ በአካባቢው ስለሚገኙ, ጠቅ ያድርጉ አለፈ.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
በመጨረሻም ወደ የፕሮጀክቱ መቼቶች እንሄዳለን.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
የመሰብሰቢያ ደረጃዎችን እንጨምር፣ ይህንን ለማድረግ ጠቅ ያድርጉ፡ ደረጃዎችን ይገንቡ -> የግንባታ ደረጃን ያክሉ.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
እዚህ እንመርጣለን:

  • የሩጫ አይነት -> የትእዛዝ መሾመር
  • አሂድ -> ብጁ ስክሪፕት።

በፕሮጀክት ማጠናቀር ወቅት ትንተና ስለምንሰራ፣ስብሰባ እና ትንተና አንድ እርምጃ መሆን ስላለበት መስኩን ሙላ ብጁ ስክሪፕት:

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
የግለሰብ ደረጃዎችን በኋላ እንመለከታለን. ተንታኙን መጫን፣ ፕሮጀክቱን መሰብሰብ፣ መተንተን፣ ሪፖርቱን ማውጣት እና መቅረጽ አስራ አንድ የኮድ መስመሮችን ብቻ መውሰድ አስፈላጊ ነው።

እኛ ማድረግ ያለብን የመጨረሻው ነገር የአካባቢ ተለዋዋጮችን ማቀናበር ነው፣ ይህም ተነባቢነታቸውን ለማሻሻል አንዳንድ መንገዶችን ገልጫለሁ። ይህንን ለማድረግ ወደ ፊት እንቀጥል፡- መለኪያዎች -> አዲስ መለኪያ ያክሉ እና ሶስት ተለዋዋጮችን ያክሉ።

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
ማድረግ ያለብዎት አዝራሩን መጫን ብቻ ነው ሩጫ በላይኛው ቀኝ ጥግ ላይ. ፕሮጀክቱ እየተሰበሰበ እና እየተተነተነ, ስለ ስክሪፕቱ እነግርዎታለሁ.

ቀጥታ ስክሪፕት።

በመጀመሪያ፣ የቅርብ ጊዜውን የ PVS-ስቱዲዮ ስርጭት ማውረድ አለብን። ለዚህ የ Chocolatey ጥቅል አስተዳዳሪን እንጠቀማለን. ስለዚህ ጉዳይ የበለጠ ለማወቅ ለሚፈልጉ, ተዛማጅ አለ ጽሑፍ:

choco install pvs-studio -y

በመቀጠል የ CLMonitor ፕሮጀክት ግንባታ መከታተያ መገልገያን እናስጀምር።

%CLmon% monitor –-attach

ከዚያም ፕሮጀክቱን እንደ የአካባቢ ተለዋዋጭ እንገነባለን ኤም.ኤስ.ቢ. ለመገንባት የሚያስፈልገኝ የ MSBuild ሥሪት መንገድ ነው።

%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable

ለPVS-ስቱዲዮ የመግቢያ እና የፍቃድ ቁልፍ እናስገባ፡-

%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%

ግንባታው ከተጠናቀቀ በኋላ ቀድሞ የተቀነባበሩ ፋይሎችን እና የማይንቀሳቀስ ትንታኔን ለማመንጨት CLMonitor ን እንደገና ያሂዱ፡

%CLmon% analyze -l "c:ptest.plog"

ከዚያም ከስርጭታችን ሌላ መገልገያ እንጠቀማለን. PlogConverter ሪፖርትን ከመደበኛ ቅርጸት ወደ TeamCity-ተኮር ቅርጸት ይለውጠዋል። ለዚህም ምስጋና ይግባውና በግንባታ መስኮቱ ውስጥ በቀጥታ ማየት እንችላለን.

%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"

የመጨረሻው እርምጃ የተቀረፀውን ሪፖርት ወደ ውስጥ ማሳየት ነው። ስቶትበ TeamCity ተንታኝ የሚወሰድበት።

type "C:tempptest.plog_TeamCity.txt"

ሙሉ ስክሪፕት ኮድ፡-

choco install pvs-studio -y
%CLmon% monitor --attach
set platform=x64
%MSB% %ProjPath% /t:clean
%MSB% %ProjPath% /t:rebuild /p:configuration=release
%MSB% %ProjPath% /t:g2
%MSB% %ProjPath% /t:PublishPortable
%PVS-Studio_cmd% credentials --username %PVS_Name% --serialNumber %PVS_Key%
%CLmon% analyze -l "c:ptest.plog"
%PlogConverter% "c:ptest.plog" --renderTypes=TeamCity -o "C:temp"
type "C:tempptest.plog_TeamCity.txt"

ይህ በእንዲህ እንዳለ የፕሮጀክቱ ስብሰባ እና ትንተና በተሳካ ሁኔታ ተጠናቅቋል, ወደ ትሩ መሄድ እንችላለን ፕሮጀክቶች እና ኡቤዲትስያ в эtom.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
አሁን ጠቅ እናድርግ አጠቃላይ ምርመራዎችየትንታኔ ዘገባውን ለማየት፡-

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
ማስጠንቀቂያዎች በምርመራ ደንብ ቁጥሮች ይመደባሉ. በኮዱ ውስጥ ለማሰስ ከማስጠንቀቂያው ጋር ያለውን የመስመር ቁጥር ጠቅ ማድረግ ያስፈልግዎታል። በላይኛው ቀኝ ጥግ ላይ ያለውን የጥያቄ ምልክት ጠቅ ማድረግ ከሰነድ ጋር አዲስ ትር ይከፍታል። እንዲሁም በተንታኙ ማስጠንቀቂያ የመስመር ቁጥሩን ጠቅ በማድረግ በኮዱ ውስጥ ማሰስ ይችላሉ። በሚጠቀሙበት ጊዜ ከርቀት ኮምፒተር ማሰስ ይቻላል ምንጭTreeRoot ምልክት ማድረጊያ. በዚህ የመተንተን ዘዴ ላይ ፍላጎት ያለው ማንኛውም ሰው ከተዛማጁ ክፍል ጋር እራሱን ማወቅ ይችላል። ሰነድ.

የተንታኙን ውጤቶች በመመልከት ላይ

ግንባታውን ማሰማራት እና ማዋቀር ከጨረስን በኋላ፣ በምንመለከተው ፕሮጀክት ውስጥ የተገኙ አንዳንድ አስደሳች ማስጠንቀቂያዎችን እንመልከት።

ማስጠንቀቂያ N1

V773 [CWE-401] ልዩነቱ የ'ውጤት' ጠቋሚውን ሳይለቅ ተጣለ። የማስታወስ ችሎታ መፍሰስ ይቻላል. libopenrct2 ObjectFactory.cpp 443

Object* CreateObjectFromJson(....)
{
  Object* result = nullptr;
  ....
  result = CreateObject(entry);
  ....
  if (readContext.WasError())
  {
    throw std::runtime_error("Object has errors");
  }
  ....
}

Object* CreateObject(const rct_object_entry& entry)
{
  Object* result;
  switch (entry.GetType())
  {
    case OBJECT_TYPE_RIDE:
      result = new RideObject(entry);
      break;
    case OBJECT_TYPE_SMALL_SCENERY:
      result = new SmallSceneryObject(entry);
      break;
    case OBJECT_TYPE_LARGE_SCENERY:
      result = new LargeSceneryObject(entry);
      break;
    ....
    default:
      throw std::runtime_error("Invalid object type");
  }
  return result;
}

ተንታኙ ማህደረ ትውስታን በተለዋዋጭነት ከመደብ በኋላ የሆነ ስህተት አስተውሏል። ነገር ይፍጠሩልዩ ሁኔታ ሲፈጠር, ማህደረ ትውስታው አይጸዳም, እና የማስታወሻ ፍሳሽ ይከሰታል.

ማስጠንቀቂያ N2

V501 በ'|' በስተግራ እና በስተቀኝ ተመሳሳይ ንዑስ አገላለጾች አሉ '(1ULL << WIDX_MONTH_BOX)' ኦፕሬተር. libopenrct2ui Cheats.cpp 487

static uint64_t window_cheats_page_enabled_widgets[] = 
{
  MAIN_CHEAT_ENABLED_WIDGETS |
  (1ULL << WIDX_NO_MONEY) |
  (1ULL << WIDX_ADD_SET_MONEY_GROUP) |
  (1ULL << WIDX_MONEY_SPINNER) |
  (1ULL << WIDX_MONEY_SPINNER_INCREMENT) |
  (1ULL << WIDX_MONEY_SPINNER_DECREMENT) |
  (1ULL << WIDX_ADD_MONEY) |
  (1ULL << WIDX_SET_MONEY) |
  (1ULL << WIDX_CLEAR_LOAN) |
  (1ULL << WIDX_DATE_SET) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_MONTH_UP) |
  (1ULL << WIDX_MONTH_DOWN) |
  (1ULL << WIDX_YEAR_BOX) |
  (1ULL << WIDX_YEAR_UP) |
  (1ULL << WIDX_YEAR_DOWN) |
  (1ULL << WIDX_DAY_BOX) |
  (1ULL << WIDX_DAY_UP) |
  (1ULL << WIDX_DAY_DOWN) |
  (1ULL << WIDX_MONTH_BOX) |  // <=
  (1ULL << WIDX_DATE_GROUP) |
  (1ULL << WIDX_DATE_RESET),
  ....
};

ከስታቲክ ተንታኝ በስተቀር ጥቂት ሰዎች ይህንን የትኩረት ፈተና ማለፍ ይችላሉ። ይህ የቅጅ-መለጠፍ ምሳሌ ለዚህ በትክክል ጥሩ ነው።

ማስጠንቀቂያዎች N3

V703 የ'ባንዲራዎች' መስክ በተገኘው ክፍል 'RCT12BannerElement' መስክን በመሠረታዊ ክፍል 'RCT12TileElementBase' ላይ መጻፉ እንግዳ ነገር ነው። መስመሮችን ያረጋግጡ: RCT12.h: 570, RCT12.h: 259. libopenrct2 RCT12.h 570

struct RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};
struct rct1_peep : RCT12SpriteBase
{
  ....
  uint8_t flags;
  ....
};

እርግጥ ነው, በመሠረታዊ ክፍል ውስጥ እና በትውልድ ውስጥ ተመሳሳይ ስም ያለው ተለዋዋጭ መጠቀም ሁልጊዜ ስህተት አይደለም. ይሁን እንጂ የውርስ ቴክኖሎጂ ራሱ ሁሉም የወላጅ ክፍል መስኮች በልጁ ክፍል ውስጥ እንደሚገኙ ይገምታል. በወራሽ ውስጥ ተመሳሳይ ስም ያላቸውን መስኮች በማወጅ, ግራ መጋባትን እንፈጥራለን.

ማስጠንቀቂያ N4

V793 የ'imageDirection/8' መግለጫ ውጤት የሁኔታው አካል መሆኑ እንግዳ ነገር ነው። ምናልባት, ይህ መግለጫ ከሌላ ነገር ጋር መወዳደር ነበረበት. libopenrct2 ObservationTower.cpp 38

void vehicle_visual_observation_tower(...., int32_t imageDirection, ....)
{
  if ((imageDirection / 8) && (imageDirection / 8) != 3)
  {
    ....
  }
  ....
}

እስቲ ጠለቅ ብለን እንመርምር። አገላለጽ ምስል አቅጣጫ/8 ከሆነ ውሸት ይሆናል። ምስል አቅጣጫ ከ -7 እስከ 7 ባለው ክልል ውስጥ ነው። ሁለተኛ ክፍል፡- (ምስል አቅጣጫ / 8) != 3 ቼኮች ምስል አቅጣጫ ከክልል ውጭ መሆን፡- ከ -31 እስከ -24 እና ከ24 እስከ 31 በቅደም ተከተል። በተወሰነ ክልል ውስጥ ለመካተት ቁጥሮችን በዚህ መንገድ መፈተሸ ለእኔ እንግዳ ይመስላል እና ምንም እንኳን በዚህ ኮድ ውስጥ ምንም ስህተት ባይኖርም ፣ እነዚህን ሁኔታዎች የበለጠ ግልፅ ለማድረግ እንደገና ለመፃፍ እመክራለሁ ። ይህ ይህን ኮድ ለማንበብ እና ለሚጠብቁ ሰዎች ህይወት በጣም ቀላል ያደርገዋል።

ማስጠንቀቂያ N5

V587 የዚህ ዓይነቱ ያልተለመደ ቅደም ተከተል: A = B; B = A;. መስመሮችን ያረጋግጡ: 1115, 1118. libopenrct2ui MouseInput.cpp 1118

void process_mouse_over(....)
{
  ....
  switch (window->widgets[widgetId].type)
  {
    case WWT_VIEWPORT:
      ebx = 0;
      edi = cursorId;                                 // <=
      // Window event WE_UNKNOWN_0E was called here,
      // but no windows actually implemented a handler and
      // it's not known what it was for
      cursorId = edi;                                 // <=
      if ((ebx & 0xFF) != 0)
      {
        set_cursor(cursorId);
        return;
      }
      break;
      ....
  }
  ....
}

ይህ የኮድ ቁርጥራጭ አብዛኛውን ጊዜ የተገኘው በመፍረስ ነው። ከዚያም በግራ በኩል ባለው አስተያየት በመመዘን የማይሰራ ኮድ ክፍል ተወግዷል። ሆኖም፣ አሁንም ሁለት ሁለት ኦፕሬሽኖች ይቀራሉ cursorId, ይህም ደግሞ ብዙ ትርጉም አይሰጥም.

ማስጠንቀቂያ N6

V1004 [CWE-476] 'ተጫዋች' ጠቋሚው በ nullptr ላይ ከተረጋገጠ በኋላ ደህንነቱ ባልተጠበቀ ሁኔታ ጥቅም ላይ ውሏል። መስመሮችን ያረጋግጡ: 2085, 2094. libopenrct2 Network.cpp 2094

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)                                          // <=
    {
      *player = pendingPlayer;
       if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
       {
         _serverConnection->Player = player;
       }
    }
    newPlayers.push_back(player->Id);                    // <=
  }
  ....
}

ይህ ኮድ ለማረም በጣም ቀላል ነው፣ ለሶስተኛ ጊዜ ማረጋገጥ ብቻ ያስፈልግዎታል ተጫዋች ወደ ባዶ ጠቋሚ ወይም ወደ ሁኔታዊ መግለጫው አካል ይጨምሩ። ሁለተኛውን አማራጭ እጠቁማለሁ-

void Network::ProcessPlayerList()
{
  ....
  auto* player = GetPlayerByID(pendingPlayer.Id);
  if (player == nullptr)
  {
    // Add new player.
    player = AddPlayer("", "");
    if (player)
    {
      *player = pendingPlayer;
      if (player->Flags & NETWORK_PLAYER_FLAG_ISSERVER)
      {
        _serverConnection->Player = player;
      }
      newPlayers.push_back(player->Id);
    }
  }
  ....
}

ማስጠንቀቂያ N7

V547 [CWE-570] 'ስም == nullptr' የሚለው አገላለጽ ሁልጊዜ ውሸት ነው። libopenrct2 ServerList.cpp 102

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    ....
  }
  else
  {
    ....
    entry.name = (name == nullptr ? "" : json_string_value(name));
    ....
  }
  ....
}

ለማንበብ አስቸጋሪ የሆነ የኮድ መስመርን በአንድ ጊዜ ማስወገድ እና ችግሩን በመፈተሽ መፍታት ይችላሉ nullptr. ኮዱን በሚከተለው መልኩ እንዲቀይሩ ሀሳብ አቀርባለሁ።

std::optional<ServerListEntry> ServerListEntry::FromJson(...)
{
  auto name = json_object_get(server, "name");
  .....
  if (name == nullptr || version == nullptr)
  {
    name = ""
    ....
  }
  else
  {
    ....
    entry.name = json_string_value(name);
    ....
  }
  ....
}

ማስጠንቀቂያ N8

V1048 [CWE-1164] የ'ColumnHeaderPressedCurrentState' ተለዋዋጭ ተመሳሳይ እሴት ተሰጥቷል። libopenrc2ui CustomListView.cpp 510

void CustomListView::MouseUp(....)
{
  ....
  if (!ColumnHeaderPressedCurrentState)
  {
    ColumnHeaderPressed = std::nullopt;
    ColumnHeaderPressedCurrentState = false;
    Invalidate();
  }
}

ኮዱ በጣም እንግዳ ይመስላል። በሁኔታው ላይ ወይም ተለዋዋጭውን እንደገና ሲመደብ የትየባ ትየባ የነበረ ይመስላል የአምድ ራስጌ ፕሬስCurrentState ትርጓሜዎች የሐሰት.

መደምደሚያ

እንደምናየው፣ የ PVS-Studio static analyzerን ከእርስዎ የTeamCity ፕሮጀክት ጋር ማዋሃድ በጣም ቀላል ነው። ይህንን ለማድረግ አንድ ትንሽ የውቅር ፋይል ብቻ መጻፍ በቂ ነው. ኮዱን መፈተሽ ከተሰበሰበ በኋላ ወዲያውኑ ችግሮችን ለይተው እንዲያውቁ ያስችልዎታል, ይህም ውስብስብነት እና ለውጦች አሁንም ዝቅተኛ ሲሆኑ እነሱን ለማስወገድ ይረዳል.

PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የፕሮጀክቱ ትንተና ክፈት ሮለር ኮስተር ታይኮን 2
ይህንን ጽሑፍ ለእንግሊዝኛ ተናጋሪ ታዳሚዎች ማጋራት ከፈለጉ እባክዎን የትርጉም ማያያዣውን ይጠቀሙ-ቭላዲላቭ ስቶልያሮቭ። PVS-ስቱዲዮ እና ቀጣይነት ያለው ውህደት: TeamCity. የOpen RollerCoaster Tycoon 2 ፕሮጀክት ትንተና.

ምንጭ: hab.com

አስተያየት ያክሉ