# Tuist 01: Kirish va o'rnatish — Tuist nima, qaysi muammoni hal qiladi va 5 daqiqada birinchi loyiha

> **Holat:** 2026-yil oktabr. Bu dars Tuist nima ekanini, u qaysi aniq muammoni yechishini va 5 daqiqada birinchi loyihani ishga tushirishni o'rgatadi. Kod misollari **Tuist 4.211.1**, **Xcode 27.1 (27A9275)** va **Swift 6.4** bilan **Apple M4 Pro** (12 core, 24 GB) da tekshirilgan.

> **Bu darsdan keyin siz:** Tuist'ni o'rnatib, o'z qo'lingiz bilan birinchi modulli iOS loyihasini generatsiya qilib, simulyatorda ishga tushira olasiz — va nima uchun bu usul `project.pbxproj` muammosini butunlay yo'q qilishini tushunasiz.

- `project.pbxproj` nega jamoaviy ishda azob berishini — haqiqiy `git merge` konflikti misolida ko'rasiz;
- Tuist'ning 2026-dagi ikki yuzini (project **generator** + tezlik/insight **platforma**si) ajrata olasiz;
- `mise` yoki Homebrew bilan Tuist'ni o'rnatib, versiyani jamoa uchun qotirasiz (`tuist@4.211.1`);
- `tuist init` → `tuist generate` → `xcodebuild` → `tuist test` zanjirini o'z o'lchovlaringiz bilan bajarasiz;
- 2026-dagi CLI buyruqlarini bilasiz va eski darsliklardagi eskirgan buyruqlardan (`tuist focus`, `tuist fetch`, `Config.swift`) qochasiz.

## Mundarija

1. [Muammo: `project.pbxproj` va jamoaviy ish](#muammo)
2. [Qulaylik narxi: implicit bog'liqliklar](#cost)
3. [Tuist nima (2026): generator va platforma](#nima)
4. [Qanday ishlaydi: manifest → graph → Xcode loyihasi](#qanday)
5. [O'rnatish: mise, Homebrew va versiyani qotirish](#ornatish)
6. [5 daqiqada birinchi loyiha](#besh-daqiqa)
7. [Nega arziydi: real jamoalar va o'z o'lchovlarim](#motivatsiya)
8. [CLI xaritasi (4.211.1)](#cli)
9. [Eski darsliklar nimani noto'g'ri o'rgatadi](#ozgargan)
10. [Amaliy mashqlar](#mashqlar)
11. [O'zingizni tekshiring](#checklist)
12. [Xulosa](#xulosa)
13. [Manbalar](#manbalar)

---

## 1. Muammo: `project.pbxproj` va jamoaviy ish {#muammo}

Har bir Xcode loyihasining ichida `MyApp.xcodeproj/project.pbxproj` degan fayl bor. Bu — Xcode loyihangizning "miyasi": qaysi fayllar qaysi target'ga tegishli, qanday build setting'lar bor, qaysi framework'lar linklanadi — hammasi shu faylda yoziladi. Muammo shundaki, bu fayl **odam uchun emas, mashina uchun** yozilgan. Ichida har bir element uchun 24 belgili hex identifikator (masalan `00F38421DE977174828DBA92`) bo'ladi.

Keling, buni gapirib o'tirmasdan, haqiqatda ko'raylik. Men Tuist bilan kichik bir loyiha generatsiya qildim, uning `project.pbxproj` faylini git'ga qo'ydim (ya'ni klassik "loyihani commit qilamiz" usuli), so'ng ikki dasturchi ikki alohida branch'da bittadan yangi ekran fayli qo'shdi:

```bash
# Azim o'z branch'ida Profil ekranini qo'shadi
git checkout -b feature/profile main
# ... Sources/ProfileView.swift yaratildi, loyiha qayta generatsiya qilindi ...
git commit -am "added profile screen"

# Dilnoza xuddi shu asosdan (main) Sozlamalar ekranini qo'shadi
git checkout -b feature/settings main
# ... Sources/SettingsView.swift yaratildi, loyiha qayta generatsiya qilindi ...
git commit -am "added settings screen"

# Endi Azim Dilnozaning branch'ini o'ziga qo'shib olmoqchi:
git checkout feature/profile
git merge feature/settings
```

Natija (men haqiqatda olgan chiqish — hech narsa o'ylab topilmagan):

```text
Auto-merging ConflictDemo.xcodeproj/project.pbxproj
CONFLICT (content): Merge conflict in ConflictDemo.xcodeproj/project.pbxproj
Automatic merge failed; fix conflicts and then commit the result.
```

Faylning ichi esa shunday ko'rinadi:

```text
		83694910F51808EF05647B16 /* Sources */ = {
			isa = PBXGroup;
			children = (
				45BB604057E80130C7A38F16 /* App.swift */,
<<<<<<< HEAD
				6035B7B5B8E94B0548015005 /* ProfileView.swift */,
=======
				3F402DE11DAC1368B68786C9 /* SettingsView.swift */,
>>>>>>> feature/settings
			);
			path = Sources;
			sourceTree = "<group>";
		};
```

Va yana bir konflikt "Sources" build phase'ida:

```text
/* Begin PBXSourcesBuildPhase section */
		9BB09A959275F82566850030 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				39D7A3CC2E102EC78ACFE482 /* App.swift in Sources */,
<<<<<<< HEAD
				0BB022FF2F2F7336BBFE2F1A /* ProfileView.swift in Sources */,
=======
				8EC79921F6CBA18B331E5F1C /* SettingsView.swift in Sources */,
>>>>>>> feature/settings
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
```

Hech kim bu fayllarni qo'lda tahrir qilmadi — ikkala dasturchi ham shunchaki Xcode'da (yoki Tuist bilan) bittadan fayl qo'shdi. Ammo ikkalasi ham `files` va `children` ro'yxatining **aynan o'sha joyiga** yangi qator qo'shgani uchun `git` bu ikki o'zgarishni avtomatik birlashtira olmadi. Endi kimdir bu hex ID'larni tushunib, qaysi qatorni qoldirib, qaysi `<<<<<<<`/`=======`/`>>>>>>>` belgilarni o'chirishni hal qilishi kerak. Bitta qavs yoki vergul adashsa — butun loyiha Xcode'da ochilmay qoladi.

![Chapda haqiqiy project.pbxproj merge konflikti (ikki branch ikkita fayl qo'shdi), o'ngda Tuist yechimi: Project.swift git'da, .xcodeproj gitignore'da.](/lessons/images/tuist/tuist_01_pbxproj_vs_manifest.svg)

Diagrammaning chap tomoni yuqoridagi haqiqiy konfliktni ko'rsatadi; o'ng tomoni Tuist qanday qilib bu muammoni ildizidan yo'q qilishini — `Project.swift` ni (odam o'qiydigan Swift kod) commit qilib, generatsiyalangan `.xcodeproj` ni esa `.gitignore` ga olib — ko'rsatadi.

> **🧠 Esda tuting:** Konfliktning ildizi — generatsiyalangan ikkilamchi (derived) faylni Git'da saqlash. `project.pbxproj` sizning kodingiz emas, u sizning sozlamalaringizdan **hosil bo'lgan** fayl. Tuist aynan shu hosilani Git'dan chiqarib tashlaydi: siz sababni (`Project.swift`) saqlaysiz, natijani (`project.pbxproj`) esa har kim o'z mashinasida qayta generatsiya qiladi.

### Modern nuans: Xcode 16 "synchronized folders" buni biroz yumshatadi

Adolatli bo'lish uchun ayni haqiqatni ham aytish kerak. Yuqoridagi konflikt loyiha fayllarni **bittalab** `project.pbxproj` da ro'yxatga olgani uchun yuzaga keldi (bu Xcode'ning yillardan beri davom etgan odati). Xcode 16 dan boshlab "synchronized folders" (sinxronlangan papkalar) paydo bo'ldi — papkani butunlab target'ga biriktirasiz, va undagi fayllar `pbxproj` da alohida ro'yxatga olinmaydi. Tuist buni `buildableFolders` orqali qo'llaydi (keyingi darsda batafsil).

Men buni ham tekshirdim: `buildableFolders` ishlatadigan loyihada yangi `AboutView.swift` faylini papkaga qo'shib, qayta generatsiya qildim — va `project.pbxproj` **umuman o'zgarmadi** (fayl md5'i bir xil qoldi: `685b13eff0ee66f641215cb1b1684b70` → `685b13eff0ee66f641215cb1b1684b70`, `git diff` bo'sh).

> **⚠️ Diqqat:** Demak "pbxproj konflikti"ning fayl-qo'shish turi `buildableFolders` bilan kamayadi. Lekin build setting'lar, target'lar, scheme'lar, bog'liqliklar o'zgarganda `pbxproj` baribir o'zgaradi — va agar siz uni commit qilsangiz, baribir konflikt bo'lishi mumkin. Tuist'ning asl yechimi "fayllarni yaxshiroq ro'yxatga olish" emas, balki **generatsiyalangan loyihani umuman commit qilmaslik**dir. Buni Tuist'ning o'zi ham tan oladi: buildable folders changelog'ida "bu konfliktlar bizning ish jarayonimizda tez-tez uchramasdi, asl yutuq — qayta generatsiya qilish shart emasligi" deyilgan.

Bundan tashqari `project.pbxproj` bilan bog'liq yana ikki og'riq bor, va ularni `buildableFolders` yecha olmaydi:

1. **Inkonsistent build setting'lar.** 40 ta target'li loyihada "hammasi `SWIFT_VERSION = 6.0` bo'lsin" degan qoidani Xcode interfeysida kafolatlash qiyin — kimdir bitta target'da uni qo'lda o'zgartiradi va hech kim sezmay qoladi.
2. **Arxitektura ko'rinmaydi.** Qaysi modul qaysi modulga bog'langan, qayerda aylanma bog'liqlik (circular dependency) bor — `pbxproj` ni ochib bilib bo'lmaydi.

Keyingi bo'limda esa eng nozik, lekin eng muhim muammoni ko'ramiz: **implicit (yashirin) bog'liqliklar**.

---

## 2. Qulaylik narxi: implicit bog'liqliklar {#cost}

Tuist jamoasining o'zi "The cost of convenience" (qulaylikning narxi) nomli hujjatida Xcode falsafasini shunday tushuntiradi: Apple Xcode'ni **kichik loyihalar uchun qulay** bo'lishga optimallashtirgan. Buning uchun ko'p narsani "yashirin" (implicit) qilib qo'ygan — ya'ni build paytida avtomatik hal qilinadigan. Kichik loyihada bu qulay. Katta loyihada esa aynan shu yashirinlik muammolarning manbai bo'ladi.

Eng klassik misol — **umumiy "built products" papkasi**. Xcode barcha target'larning kompilyatsiya natijalarini (binary, framework) bitta derived data papkasiga joylaydi, va bu papka boshqa target'larga ham ko'rinadi. Oqibatda:

> Bitta target ikkinchisiga **hech qayerda yozilmagan holda** bog'lanib qolishi mumkin. Build mashinangizda (derived data'da tasodifan kerakli binary turgani uchun) o'tadi, CI serverda esa (u yerda holat boshqacha) **compile bo'lmaydi**.

Bu — har bir iOS jamoasi hayotida bo'lgan "menikida ishlayapti-ku" (works on my machine) muammosining aniq texnik sababi. Tuist hujjati buni shunday ta'riflaydi (tarjima): _"build lokal'da derived data'dagi qandaydir holat tufayli o'tishi mumkin — u singleton kabi ishlaydi — lekin CI'da holat boshqacha bo'lgani uchun compile bo'lmaydi."_

Yashirin bog'liqliklar yana ikki joyda og'riq beradi:

- **SwiftUI Preview'lar ishonchsiz bo'ladi.** Preview va Swift Macro'lar ishlashi uchun build tizimi tahrir qilinayotgan fayldan boshlab butun bog'liqlik grafigini aniq bilishi kerak. Grafik qanchalik yashirin bo'lsa, build tizimiga shunchalik qiyin — shuning uchun ko'p dasturchilar "Preview baribir ishlamaydi" deb undan voz kechgan.
- **Mergeable libraries kabi build paytida hal qilinadigan narsalar.** Target static'mi yoki dynamic'mi — buni build paytidagi setting'lardan aniqlash grafikni yana ham noaniq qiladi.

Tuist bu muammolarni **explicit** (aniq) qilib yechadi: siz bog'liqliklarni `Project.swift` da ochiq yozasiz, Tuist esa generatsiya paytida grafikni quradi va tekshiradi. Tuist hujjatining o'z so'zi bilan:

> _"Tuist'ning rolini shunday ta'riflasa bo'ladi: u loyihalarning implicit (yashirin) aniqlanishining oldini oladi va explicitlikdan foydalanib yaxshiroq developer experience beradi (validatsiya, optimizatsiya). Bazel kabi vositalar buni yana chuqurroq — build tizimi darajasiga — olib boradi."_

> **🧠 Esda tuting:** Bu — Tuist va Bazel'ning umumiy falsafasi: **explicitlik (aniqlik) — miqyos (scale) kaliti.** Farqi shundaki, Tuist Apple'ning `xcodebuild` build tizimini saqlab, uning ustida ishlaydi; Bazel esa o'z build tizimini olib keladi. Shu sababli bu kursning ikkala moduli — [Tuist](/ios-lessons/tuist-01-kirish-va-ornatish) va [Bazel](/ios-lessons/bazel-01-kirish) — bitta g'oyaning ikki darajasi.

> **💡 Pro tip:** Tuist yashirin bog'liqliklarni topish uchun alohida buyruq beradi: `tuist inspect dependencies --only implicit`. Uni CI'da ishga tushirsangiz, kodingizga yashirin bog'liqlik kirib qolsa — build emas, **CI tekshiruvi** qulaydi, ya'ni muammoni erta ushlaysiz. Buni [4-dars](/ios-lessons/tuist-04-dependencies) da amalda ko'ramiz.

---

## 3. Tuist nima (2026): generator va platforma {#nima}

2026-yilda Tuist'ni bitta jumlada ta'riflash kam. Uning **ikki yuzi** bor:

**1-yuz — Project generator (CLI, bepul, hisob shart emas).** Siz loyiha strukturasini Swift manifestlarda (`Project.swift`, `Tuist.swift`) yozasiz, `tuist generate` deysiz, Tuist esa toza `.xcodeproj`/`.xcworkspace` yaratib beradi. Bu yerga `tuist graph` (bog'liqlik grafigi), `tuist edit` (manifestni autocomplete bilan tahrirlash), `tuist migration` (Xcode'dan ko'chirish), `tuist scaffold` (shablonlar) va `tuist inspect` (implicit bog'liqlik tekshiruvi) kiradi. **Bularning hammasi hisobsiz, bepul ishlaydi.**

**2-yuz — Platforma (server/hisob bilan kuchayadi).** Bu loyihangizni tezlashtiradi va unga "ko'z" beradi:

- **Module (binary) cache** — o'zgarmagan modullarni tayyor `.xcframework` sifatida qayta ishlatish;
- **Selective testing** — faqat o'zgargan modullar testini ishga tushirish;
- **Xcode compilation cache** — Apple'ning Xcode 26+ dagi kompilyatsiya keshiga masofaviy backend;
- **Build / Test / Bundle insights** — build vaqti, flaky testlar, ilova hajmi tahlili;
- **Previews** (`tuist share`), **Swift Package Registry**, **Runners** (CI).

![Tuist'ning ikki yuzi: chapda bepul generator (CLI), o'ngda server/hisob bilan ishlaydigan platforma; pastda — 2026-dan beri Bazel va Gradle'ni ham quvvatlaydi.](/lessons/images/tuist/tuist_01_features_map.svg)

> **🧠 Esda tuting:** Module cache va selective testing **lokal rejimda hisobsiz ham ishlaydi** (buni keyinroq o'z mashinamda ko'rsataman). Lekin ularni jamoa bo'lib birga ulashish (masofaviy kesh), insights, previews va runners uchun Tuist hisobi/serveri kerak. "Avval bepul lokal, kerak bo'lsa server" — to'g'ri yondashuv.

Yana bir muhim yangilik: **Tuist endi faqat Xcode uchun emas.** 2026-yil sentyabrdan beri Tuist serveri **Bazel** va **Gradle** loyihalarini ham keshlaydi (Bazel uchun REAPI masofaviy kesh + Build Event Protocol orqali insights; sozlash ikki buyruq: `tuist auth login`, keyin har repo uchun `tuist bazel setup`). Ya'ni Tuist nafaqat "Xcode project generatori", balki bir nechta build tizimiga xizmat qiluvchi platformaga aylanyapti.

> **⚠️ Diqqat:** "Tuist Cloud" nomi endi yo'q — u shunchaki **Tuist** (server + dashboard, `tuist.dev`) deb ataladi. Eski darsliklarda "Tuist Cloud" ni uchratsangiz, bu o'sha mahsulotning eski nomi.

### Tarix va falsafa (qisqa)

Tuist 2017-yildan beri rivojlanadi va uning asosiy g'oyasi boshidanoq bir xil: **Infrastructure as Code** tamoyilini iOS loyihalariga olib kirish. Siz loyihani "qo'lda sichqoncha bilan" emas, kod bilan ta'riflaysiz; kod esa versiyalanadi, review qilinadi va qayta ishlatiladi. Versiyalar tarixida muhim bosqich — **Tuist 3 → 4** o'tishi (2024), unda ko'p narsa o'zgardi (`tuist fetch` → `tuist install`, `Config.swift` → `Tuist.swift` va hokazo — bularni 9-bo'limda ko'ramiz). Hozir **Tuist 5 yo'q**; eng so'nggi barqaror versiya 4.x liniyasida.

---

## 4. Qanday ishlaydi: manifest → graph → Xcode loyihasi {#qanday}

Tuist'ning yuragi — oddiy uch bosqichli jarayon:

![Tuist jarayoni: 1) siz Swift manifestlarni yozasiz, 2) tuist generate bog'liqlik grafigini quradi va tekshiradi, 3) .xcworkspace/.xcodeproj/Derived yaratiladi; manifestlar git'ga, generatsiyalangan fayllar gitignore'ga.](/lessons/images/tuist/tuist_01_how_it_works.svg)

1. **Siz Swift manifestlarni yozasiz.** Kamida ikki fayl: `Tuist.swift` (global sozlama, loyiha ildizini belgilaydi) va `Project.swift` (bitta Xcode loyihasini ta'riflaydi). Tashqi paketlar uchun `Tuist/Package.swift`.
2. **`tuist generate` grafikni quradi.** Tuist manifestlarni o'qiydi (ular haqiqiy Swift kod, shuning uchun avval kompilyatsiya qilinadi — birinchi marta sekinroq, keyin keshlanadi), bog'liqlik grafigini yasaydi, xatolarni tekshiradi, keshdagi binary'larni ulaydi.
3. **Natija — Xcode loyihasi.** `App.xcworkspace`, `App.xcodeproj` va `Derived/` papkasi (Info.plist va boshqa hosila fayllar). Bular **gitignore** qilinadi.

Manifestlar — bu "sabab", generatsiyalangan loyiha — "natija". Git'da faqat sabab saqlanadi. Shuning uchun har bir dasturchi `git clone` qilib, `tuist generate` deganda **aynan bir xil** loyihani oladi — 1-bo'limdagi konflikt endi tug'ilishi mumkin emas, chunki konflikt tug'diradigan fayl Git'da yo'q.

> **🚀 Motivatsiya:** Bu bitta oddiy g'oya — "hosilani commit qilma" — jamoangizdagi eng ko'p takrorlanadigan ikki azobni birato'la yo'q qiladi: `project.pbxproj` merge konfliktlari va "menikida ishlayapti" muammosi. Qolgan hamma narsa (kesh, selective testing, insights) — shu poydevor ustiga quriladigan tezlik qavatlari.

---

## 5. O'rnatish: mise, Homebrew va versiyani qotirish {#ornatish}

Tuist macOS va Linux'da ishlaydi (Linux'da `tuist generate` kabi Xcode'ga bog'liq buyruqlar yo'q, lekin `tuist inspect bundle` kabilar ishlaydi). Rasmiy hujjat ikki yo'lni tavsiya qiladi.

### 1-usul: mise (jamoalar va CI uchun tavsiya etiladi ⭐)

[mise](https://mise.jdx.dev) — har bir loyiha uchun tool versiyasini **qotirib qo'yadigan** vosita (eski `tuistenv` o'rniga kelgan). Homebrew'dan farqi: Homebrew global bitta versiyani o'rnatadi; mise esa versiyani loyihaga (yoki global) bog'lab, jamoadagi hamma va CI bir xil versiyada ishlashini kafolatlaydi.

```bash
# Loyihada aniq versiyani o'rnatib, qotirish (tavsiya):
mise use tuist@4.211.1

# Global standart sifatida:
mise use -g tuist@4.211.1

# Eng so'nggi BARQAROR versiya (canary/RC emas):
mise use tuist@latest
```

Loyiha ildizida `mise.toml` fayli paydo bo'ladi:

```toml
# mise.toml
[tools]
tuist = "4.211.1"
```

Endi loyihani klon qilgan har kim (yoki CI) shunchaki:

```bash
mise install
```

deb yozsa — aynan `4.211.1` o'rnatiladi. Bu "menikida boshqa versiya edi" muammosini yo'q qiladi.

### 2-usul: Homebrew (faqat macOS)

```bash
brew tap tuist/tuist
brew install --formula tuist
# yoki aniq versiya:
brew install --formula tuist@4.211.1
```

> **📊 Real raqamlar:** Bu darsdagi barcha tekshiruvlar aynan shu mashinada o'rnatilgan **Tuist 4.211.1** bilan bajarilgan (Homebrew cask orqali: `brew install --cask tuist`). Tekshirish:
>
> ```bash
> tuist version
> ```
>
> ```text
> 4.211.1
> ```

### Qaysi versiyani tanlash kerak?

> **⚠️ Diqqat:** Tuist tez chiqadi. Har commit uchun _canary_ build chiqadi; barqaror _minor_ versiyalar har dushanba (~1 hafta RC bo'lib turgandan keyin) chiqariladi; _patch_ versiyalar faqat tuzatishlar olib keladi. Yozilish paytida eng so'nggi barqaror versiya `4.212.0` edi (2026-10-12), biz esa `4.211.1` (2026-10-11) bilan ishladik. **Darslik yoki jamoa loyihasida har doim aniq versiyani qotiring** (`tuist@4.211.1`), "latest" ga tayanmang — chunki ertaga "latest" boshqa bo'ladi va o'zgargan xatti-harakat sizni kutilmaganda urishi mumkin.

Shell completion (Tab bilan to'ldirish) va boshqa sozlamalar `tuist --help` orqali ko'rinadi. Keling, endi amalga o'tamiz.

---

## 6. 5 daqiqada birinchi loyiha {#besh-daqiqa}

Ikki yo'lni ko'rsataman: (A) `tuist init` bilan tayyor shablondan, (B) hammasini qo'lda yozib — ikkinchisi Tuist "ichida" nima borligini tushunish uchun eng foydali.

### A yo'li: `tuist init` (2026-da u interaktiv emas)

> **⚠️ Diqqat:** Eski darsliklar `tuist init` deb yozib, terminal savol-javob (interaktiv) berishini ko'rsatadi. 4.211.1 da `tuist init` **flaglar bilan interaktiv emas** ishlaydi. `tuist init --help` ni ko'ring: `--build-system` (qiymatlari `xcode`, `generated-xcode`, `gradle`, `bazel`), `--platform`, `--name`, `--no-server`.

```bash
mkdir SalomTuist && cd SalomTuist
tuist init --build-system generated-xcode --platform ios --name DemoApp --no-server
```

Men bu buyruqni ishga tushirganimdagi haqiqiy chiqish:

```text
ℹ︎ Creating generated project
   ✔︎ Generated project created [0.7s]
✔ Success
  You are all set to explore the Tuist universe

  Takeaways:
   ▸ Choose the project directory with 'cd DemoApp'
   ▸ Generate your project with 'tuist generate'
   ▸ Visualize your project graph with 'tuist graph'
```

U quyidagi strukturani yaratadi (haqiqiy, tekshirilgan):

```text
DemoApp/
├── .gitignore
├── Tuist.swift
├── Project.swift
├── Tuist/
│   └── Package.swift
└── DemoApp/
    ├── Sources/
    │   ├── DemoAppApp.swift
    │   └── ContentView.swift
    ├── Tests/
    │   └── DemoAppTests.swift
    └── Resources/
        └── Assets.xcassets/
```

E'tibor bering: **hech qanday `.xcodeproj` yo'q.** Papka toza.

Generatsiyalangan `Project.swift` 2026-standartida — `buildableFolders` ishlatadi:

```swift
// Project.swift (tuist init yaratgan, qisqartirildi)
import ProjectDescription

let project = Project(
    name: "DemoApp",
    targets: [
        .target(
            name: "DemoApp",
            destinations: .iOS,
            product: .app,
            bundleId: "dev.tuist.DemoApp",
            infoPlist: .extendingDefault(with: ["UILaunchScreen": ["UIColorName": "", "UIImageName": ""]]),
            buildableFolders: ["DemoApp/Sources", "DemoApp/Resources"],
            dependencies: []
        ),
        .target(
            name: "DemoAppTests",
            destinations: .iOS,
            product: .unitTests,
            bundleId: "dev.tuist.DemoAppTests",
            infoPlist: .default,
            buildableFolders: ["DemoApp/Tests"],
            dependencies: [.target(name: "DemoApp")]
        ),
    ]
)
```

Va `Tuist.swift` — eng minimal ko'rinishda:

```swift
// Tuist.swift
import ProjectDescription

let tuist = Tuist(project: .tuist())
```

> **🧠 Esda tuting:** `let tuist = Tuist(project: .tuist())` — 4.211.1 dagi eng to'g'ri minimal konfiguratsiya. Eski darsliklarda bu yerda `generationOptions: .options(enforceExplicitDependencies: true)` yozilgan bo'lishi mumkin — u **4.211.1 da deprecated** (eskirgan). Buning o'rniga yashirin bog'liqliklarni `tuist inspect dependencies --only implicit` bilan CI'da tekshiring.

### B yo'li: qo'lda — 2 modulli loyiha (men shuni to'liq tekshirdim)

Keling, "App'ga bog'langan Core modul" misolini noldan yozamiz. Struktura:

```text
SalomTuist/
├── Tuist.swift
├── Project.swift
├── Tuist/
│   └── Package.swift
├── App/Sources/
│   ├── SalomApp.swift
│   └── ContentView.swift
└── Core/
    ├── Sources/Greeter.swift
    └── Tests/GreeterTests.swift
```

`Tuist.swift` va `Tuist/Package.swift`:

```swift
// Tuist.swift
import ProjectDescription

let tuist = Tuist(project: .tuist())
```

```swift
// Tuist/Package.swift
// swift-tools-version: 6.0
import PackageDescription

let package = Package(name: "SalomTuist", dependencies: [])
```

`Project.swift` — uchta target: App (ilova), Core (static framework), CoreTests (testlar):

```swift
// Project.swift
import ProjectDescription

let project = Project(
    name: "SalomTuist",
    targets: [
        .target(
            name: "SalomApp",
            destinations: .iOS,
            product: .app,
            bundleId: "uz.azimjondev.salomtuist",
            deploymentTargets: .iOS("17.0"),
            infoPlist: .extendingDefault(with: ["UILaunchScreen": [:]]),
            buildableFolders: ["App/Sources"],
            dependencies: [.target(name: "Core")]
        ),
        .target(
            name: "Core",
            destinations: .iOS,
            product: .staticFramework,
            bundleId: "uz.azimjondev.salomtuist.core",
            deploymentTargets: .iOS("17.0"),
            buildableFolders: ["Core/Sources"]
        ),
        .target(
            name: "CoreTests",
            destinations: .iOS,
            product: .unitTests,
            bundleId: "uz.azimjondev.salomtuist.coretests",
            deploymentTargets: .iOS("17.0"),
            buildableFolders: ["Core/Tests"],
            dependencies: [.target(name: "Core")]
        ),
    ]
)
```

Swift kodlar (oddiy, lekin haqiqiy — build va test shu kod bilan o'tdi):

```swift
// Core/Sources/Greeter.swift
import Foundation

public struct Greeter {
    public init() {}

    public func salom(_ name: String) -> String {
        let trimmed = name.trimmingCharacters(in: .whitespaces)
        return trimmed.isEmpty ? "Salom, dunyo!" : "Salom, \(trimmed)!"
    }
}
```

```swift
// Core/Tests/GreeterTests.swift
import Testing
@testable import Core

struct GreeterTests {
    @Test func bushNom_dunyoniQaytaradi() {
        #expect(Greeter().salom("   ") == "Salom, dunyo!")
    }

    @Test func nomBilan_salomlashadi() {
        #expect(Greeter().salom("Azim") == "Salom, Azim!")
    }
}
```

```swift
// App/Sources/SalomApp.swift
import SwiftUI

@main
struct SalomApp: App {
    var body: some Scene {
        WindowGroup { ContentView() }
    }
}
```

```swift
// App/Sources/ContentView.swift
import Core
import SwiftUI

struct ContentView: View {
    @State private var name = ""
    private let greeter = Greeter()

    var body: some View {
        VStack(spacing: 16) {
            Text(greeter.salom(name)).font(.title)
            TextField("Ismingiz", text: $name)
                .textFieldStyle(.roundedBorder)
        }
        .padding()
    }
}
```

### Loyihani generatsiya qilamiz

```bash
tuist generate --no-open
```

Haqiqiy chiqish (men olgan):

```text
Loading and constructing the graph
It might take a while if the cache is empty
Using cache binaries for the following targets:
Generating workspace SalomTuist.xcworkspace
Generating project SalomTuist
Total time taken: 0.704s
✔ Success
  Project generated.
```

> **📊 Real raqamlar (Apple M4 Pro, Tuist 4.211.1, Xcode 27.1):** Birinchi (sovuq) generatsiya — Tuist o'z o'lchovi bo'yicha **0.704 s** (jami wall-time ~1.05 s, chunki jarayon ishga tushishi ham qo'shiladi). Manifestlar keshlangandan keyin ikkinchi generatsiya — **0.603 s** (wall ~0.88 s). `--no-open` bayrog'i Xcode'ni avtomatik ochmaslik uchun (CI va skriptlar uchun qulay).

Endi papkada quyidagilar paydo bo'ldi:

```text
SalomTuist.xcworkspace   ← Xcode shuni ochadi
SalomTuist.xcodeproj     ← generatsiyalangan (gitignore)
Derived/                 ← Info.plist va hosila fayllar (gitignore)
```

Avtomatik yaratilgan scheme'lar (`xcodebuild -list` bilan tekshirdim):

```text
Schemes:
    Core
    Generate Project
    SalomApp
    SalomTuist-Workspace
```

Ya'ni har bir test bo'lmagan target uchun bitta scheme (`SalomApp`, `Core`), bitta Workspace scheme, va bitta "Generate Project" scheme (Xcode ichidan `tuist generate` ni qayta ishga tushirish uchun).

> **⚠️ Diqqat:** `CoreTests` alohida scheme emas — u **`Core`** scheme'iga biriktirilgan. Shuning uchun keyinroq `tuist test Core` deymiz, `tuist test CoreTests` emas (bu "scheme topilmadi" xatosini beradi).

### Build va simulyatorda ishga tushirish

2026-da muhim nuans: **`tuist build <scheme>` endi loyihani build qilmaydi.** 4.211.1 da `tuist build` — bu build yozuvlarini _tekshiradigan_ buyruqlar guruhi. Haqiqiy build'ni `xcodebuild` bilan (yoki insights kerak bo'lsa `tuist xcodebuild build` bilan) qilasiz. Generatsiyalangan workspace'ni build qilamiz:

```bash
xcodebuild -workspace SalomTuist.xcworkspace -scheme SalomApp \
  -destination 'generic/platform=iOS Simulator' \
  -derivedDataPath .dd build
```

Natija:

```text
** BUILD SUCCEEDED **
```

> **📊 Real raqamlar:** Bu 2 modulli ilovaning sovuq (cold) build'i — **17.3 s** (M4 Pro, Xcode 27.1). Qaysi simulyatorlar borligini `xcrun simctl list devices available` bilan ko'rasiz; Xcode 27.1 da "iPhone 15" yo'q, shuning uchun men "iPhone 17" oilasidan foydalandim. Build uchun `generic/platform=iOS Simulator` yetarli (aniq qurilma shart emas). Ilovani simulyatorda ishga tushirish uchun Xcode'da `Cmd + R` bosing yoki `xcodebuild ... -destination 'platform=iOS Simulator,name=iPhone 17,OS=27.0'` bilan test/run qiling.

### Testlar va "selective testing" (hisobsiz, lokal)

```bash
tuist test Core --device "iPhone 17" --os 27.0
```

Birinchi ishga tushirish natijasi:

```text
Testing the following targets: CoreTests
[CoreTests] Compiling GreeterTests.swift
...
Test Succeeded
✔ Success
  The project tests ran successfully
```

Endi **hech narsa o'zgartirmasdan** aynan o'sha buyruqni qayta beraman:

```text
Loading and constructing the graph
Using cache binaries for the following targets:
Generating workspace SalomTuist.xcworkspace
Generating project SalomTuist
The scheme Core's test action has no tests to run, finishing early.
```

> **🚀 Motivatsiya (o'z o'lchovim):** Birinchi test — **25.1 s** (simulyator yuklanishi + kompilyatsiya + 2 ta Swift Testing testi). Ikkinchi marta, hech narsa o'zgarmagani uchun, Tuist testni **umuman qayta ishga tushirmaydi** — **0.94 s** da "ishga tushiradigan test yo'q" deb tugatadi. Bu — **selective testing**, va u hech qanday hisob yoki serversiz, faqat lokal mashinamda ishladi. 25 soniya → 1 soniya. Yuzlab modulli loyihada bu tamoyil (faqat o'zgargan modul testini ishga tushirish) CI vaqtini keskin kamaytiradi — masalan quyida ko'radigan Monzo'da module cache + selective testing P50 PR vaqtini 52 → 15 daqiqaga tushirgan. Selective testing'ni o'chirmoqchi bo'lsangiz: `--no-selective-testing`.

> **⚠️ Diqqat:** Selective testing **faqat Tuist generatsiyalagan loyihalarda** (`tuist test` orqali) ishlaydi va granulyarligi **target darajasida** (bitta fayl emas, butun target). Shuning uchun modullaringiz qancha mayda bo'lsa, foyda shuncha katta. Boshqa build tizimlari uchun qo'llab-quvvatlash hali "rejalashtirilgan".

### Bog'liqlik grafigini ko'rish

```bash
tuist graph --format dot --no-open
```

Natija (`graph.dot` fayli — haqiqiy chiqish):

```text
digraph {
  Core [fillcolor=coral1 shape=cylinder style=filled]
  CoreTests [fillcolor=limegreen shape=octagon style=filled]
  SalomApp [fillcolor=deepskyblue shape=box3d style=filled]
  CoreTests -> Core
  SalomApp -> Core
}
```

Ya'ni `SalomApp → Core` va `CoreTests → Core`. `--format` qiymatlari: `dot` (matn), `json`, `png`, `svg` (png/svg uchun mashinada `graphviz` o'rnatilgan bo'lishi kerak). Katta loyihada bu grafik aylanma bog'liqliklarni va "kim kimga bog'langan"ni bir qarashda ko'rsatadi.

### Manifestlarni autocomplete bilan tahrirlash: `tuist edit`

```bash
tuist edit
```

Bu buyruq vaqtinchalik Xcode loyihasi yaratib, barcha manifestlaringizni (`Project.swift`, `Tuist.swift`, helperlar) **to'liq avtomatik to'ldirish (autocomplete) bilan** ochadi — chunki manifestlar haqiqiy Swift kod. Oddiy `tuist edit` jarayonni bloklab turadi (siz tahrir qilyapsiz); `tuist edit --permanent` esa loyihani joriy papkada qoldirib, bloklamaydi.

> **💡 Pro tip:** `Project.swift` ni oddiy matn muharririda yozish o'rniga `tuist edit` dan foydalaning — `ProjectDescription` API'sidagi har bir parametr (`.target`, `destinations`, `product`...) autocomplete bilan chiqadi, va xatoni Xcode darhol ko'rsatadi.

---

## 7. Nega arziydi: real jamoalar va o'z o'lchovlarim {#motivatsiya}

Endi eng muhim savol: bu haqiqatan ham arziydimi? Avval bir ogohlantirish, keyin raqamlar.

> **⚠️ Diqqat (halol gap):** Quyidagi kompaniya raqamlarining deyarli hammasi **Tuist tomonidan e'lon qilingan** (yoki mijoz yozib, Tuist saytida chop etilgan) case-study'lardan. Bazel/Tuist/Xcode'ni bir xil loyihada yonma-yon o'lchagan **neytral (uchinchi tomon) benchmark mavjud emas** — har bir raqam bitta jamoaning o'z eski holatiga nisbatan. Shuning uchun ularni "reklama bo'lishi mumkin" deb o'qing. Men quyida har birining manbasi va sanasini ataylab ko'rsataman; eng ishonchli neytral raqamlar esa — yuqoridagi o'z mashinamdagi o'lchovlar.

**🏢 Monzo** (bank ilovasi; case-study Tuist tomonidan 2026-05-26 da chop etilgan, Monzo o'zi yozgan): ~50 dan ~200 gacha modul, 45+ iOS muhandis, 1.9M qator Swift, 20 ming unit + 8 ming snapshot test. CI bir paytlar har PR uchun 70 daqiqadan oshgan. Module cache'ni `main`'da har 30 daqiqada "isitib" turish bilan: **P50 PR vaqti 52 → 15 daqiqa (−71%)**, P90 esa 57 → 35 daqiqa (−39%). Halol nuans: Monzo'ning o'zi aytadi — **lokal build vaqtlari kesh bilan ham deyarli o'zgarmadi**; kesh asosan CI'ni tezlashtiradi, mahsulot (release) build'larida umuman ishlatilmaydi.

**🏢 Asana** (loyiha-boshqaruv ilovasi; Asana muhandislik blogi, 2023-02-21 — bu ro'yxatdagi yagona **vendor-bo'lmagan** manba): ~10 muhandis, ~300 ming qator Swift deyarli bitta target ichida edi. ~1,400 qatorli Tuist manifestini "bir necha hafta"da yozishdi, keyin ~3 oy kodni modullarga ko'chirishdi. Natija: funksiyani o'zgartirib-qayta-build qilish **45 s → 15 s** (Scalyr'da qayd etilgan median), Inbox moduli esa 30–50 s → ~4 s. Ular **Bazel o'rniga Tuist**ni tanlashdi — sababi developer experience: Bazel "juda og'ir", "yangi mental modellar talab qiladi" va breakpoint muammolari bor edi. Narxi: `git checkout` 5–15 s sekinlashdi, va "muhandislarning faqat ozchiligi" Tuist ichki ishini chuqur bilardi.

**🏢 Trendyol** (e-commerce; mijoz yozgan, Tuist chop etgan, 2024-12-16; o'z serverida self-hosted): bir oylik sinovdan keyin build vaqtlari −65%, CI 30 → 10 daqiqa; UI-testlar uchun toza Xcode muhitini tayyorlash **kamida 15 daqiqa → ~30 soniya**; selective unit test'lar fikr-qaytarishni 80% gacha tezlashtirdi. (Eslatma: Trendyol'ning 170+ dasturchisi iOS + Android — faqat iOS jamoasi o'lchovi emas.)

**🏢 monday.com** (2025-12-15): ~20 kishilik iOS jamoasi, ~200 modul; CI merge jarayoni 20+ daqiqadan (2022) ~9 daqiqaga tushdi ("CI vaqtini yarmiga qisqartirdik", module cache "muhim rol o'ynadi").

**🏢 Delivery Hero** (Logistics iOS rider ilovasi, 2026-05-26): ~115 modul; toza build 2.5 → 0.5 daqiqa; CI build+test 2.5 barobar tez.

**🏢 Toss** (Koreya fintech; 2026-10-01): ~1,000 ga yaqin modul (ko'pi Interface/Implementation/Model/Testing'ga bo'lingan). Ular profiling bilan aniqlashdi: Xcode vaqtining katta qismi bog'liqlik grafigini hisoblashga ketadi, va bu xarajat **o'zgarish hajmiga emas, modullar soniga** qarab o'sadi. ~3 oyda "focus" ish jarayonini qurishdi (bir dasturchi bitta scheme tanlaydi, qolgani tayyor `.xcframework` bo'ladi) va 1 daqiqadan kam build'lar ulushini uch barobardan ko'proq oshirishdi. Yangi muammolar ~1,000 binary'da paydo bo'ldi (framework search path'lar, hash barqarorligi). Bu — Enterprise (pullik, self-hosted) sozlama.

> **📊 Real raqamlar — mening neytral o'lchovlarim** (Apple M4 Pro, Tuist 4.211.1, Xcode 27.1, bu darsning 2 modulli loyihasi). Bu raqamlar reklama emas, sizda ham takrorlanadi:
>
> | Amal                               | Vaqt              | Shart                              |
> | ---------------------------------- | ----------------- | ---------------------------------- |
> | `tuist generate` (sovuq)           | 0.70 s            | manifestlar kompilyatsiyasi bilan  |
> | `tuist generate` (iliq)            | 0.60 s            | manifestlar keshlangan             |
> | `xcodebuild` sovuq build           | 17.3 s            | 2 target, simulyator uchun         |
> | `tuist test Core` (1-marta)        | 25.1 s            | simulyator yuklash + 2 test        |
> | `tuist test Core` (2-marta)        | **0.94 s**        | selective testing, o'zgarish yo'q  |
> | `project.pbxproj` konflikti        | 2 ta hunk         | ikki branch fayl qo'shdi (haqiqiy) |
> | fayl qo'shish (`buildableFolders`) | 0 qator o'zgarish | pbxproj md5 bir xil                |

Umumiy xulosa: kichik loyihada Tuist'ning asosiy foydasi **tezlik emas, balki tartib** — pbxproj konfliktlari yo'qoladi, loyiha struktura kodda bo'ladi, onboarding osonlashadi (`git clone` → `tuist generate` → tayyor). Tezlik yutuqlari (kesh, selective testing) modullar soni va jamoa kattalashgani sari sezila boshlaydi.

---

## 8. CLI xaritasi (4.211.1) {#cli}

`tuist --help` chiqishi buyruqlarni ish bosqichlari bo'yicha guruhlaydi. Quyida 4.211.1 dagi asosiy buyruqlar (keyingi darslarda har biri batafsil ochiladi):

| Bosqich      | Buyruq                                                           | Vazifasi                                                          |
| ------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------- |
| Boshlash     | `tuist init`                                                     | Yangi loyihani boshlash (flaglar bilan, interaktiv emas)          |
| Loyiha       | `tuist generate`                                                 | Manifestdan Xcode workspace yaratish (`run`/`list`/`show`)        |
| Loyiha       | `tuist edit`                                                     | Manifestlarni autocomplete bilan tahrirlash                       |
| Loyiha       | `tuist graph`                                                    | Bog'liqlik grafigini chizish (`dot`/`json`/`png`/`svg`)           |
| Loyiha       | `tuist dump`                                                     | Manifestni JSON ko'rinishida chiqarish                            |
| Loyiha       | `tuist clean`                                                    | Lokal artifact va keshlarni tozalash                              |
| Bog'liqlik   | `tuist install`                                                  | SPM paketlarini o'rnatish/resolve qilish                          |
| Bog'liqlik   | `tuist registry`                                                 | Tuist Swift package registry bilan ishlash                        |
| Tezlik       | `tuist cache`                                                    | Modullarni binary keshlash (`warm` — standart, `config`)          |
| Tezlik       | `tuist test`                                                     | Loyihani testlash (selective testing bilan)                       |
| Tezlik       | `tuist hash`                                                     | Kesh/selective testing hashlarini debug qilish                    |
| Tahlil       | `tuist inspect`                                                  | `dependencies` (implicit/redundant), `bundle`, `build`, `test`    |
| Tahlil       | `tuist build`                                                    | Build yozuvlarini tahlil qilish (`list`/`show`/`xcode`/`gradle`)  |
| Tahlil       | `tuist xcodebuild`                                               | `xcodebuild`ni insights/analytics bilan o'raydi                   |
| Kod ulashish | `tuist scaffold`                                                 | Shablondan yangi kod yaratish                                     |
| Kod ulashish | `tuist migration`                                                | Xcode loyihasini Tuist'ga ko'chirish yordamchilari                |
| Kod ulashish | `tuist plugin`                                                   | Plugin'larni boshqarish                                           |
| Platforma    | `tuist share` / `tuist run`                                      | Preview linkini yaratish / preview yoki scheme'ni ishga tushirish |
| Platforma    | `tuist setup` / `tuist teardown`                                 | Tuist xizmatlarini (masalan Xcode cache) sozlash/o'chirish        |
| Hisob        | `tuist auth` / `account` / `project` / `organization` / `bundle` | Hisob va server resurslari                                        |
| Boshqa       | `tuist bazel`                                                    | Bazel repo'ni Tuist cache/insights'ga ulash (`setup`/`test`)      |
| Boshqa       | `tuist version`                                                  | Joriy versiyani ko'rsatish                                        |

> **🧠 Esda tuting:** `tuist build` — bu **build buyrug'i emas** (bu 4.x da eng ko'p adashtiradigan joy). U build yozuvlarini tekshiradigan guruh. Haqiqiy build — `xcodebuild` (yoki insights uchun `tuist xcodebuild`).

---

## 9. Eski darsliklar nimani noto'g'ri o'rgatadi {#ozgargan}

Internetdagi ko'p Tuist darsliklari (va bu darsning eski versiyasi ham) 2023–2024 holatiga asoslangan. Tuist 3 → 4 o'tishida ko'p narsa o'zgardi. Agar quyidagilarni ko'rsangiz — bu eskirgan:

| Eski (eskirgan)                       | 2026 (Tuist 4.211.1)                                                  |
| ------------------------------------- | --------------------------------------------------------------------- |
| `tuist init` (interaktiv savol-javob) | `tuist init --build-system generated-xcode --platform ios --name X`   |
| `tuist focus Profile`                 | `tuist generate Profile` (all-possible cache profilni nazarda tutadi) |
| `tuist fetch`                         | `tuist install`                                                       |
| `Tuist/Dependencies.swift`            | `Tuist/Package.swift` (+ `#if TUIST` ichida `PackageSettings`)        |
| `Config.swift`                        | `Tuist.swift`                                                         |
| `tuist build MyScheme` (build uchun)  | build — `xcodebuild` bilan; `tuist build` endi tahlil guruhi          |
| `--no-cache`                          | `--no-binary-cache` → endi `--cache-profile none`                     |
| `tuistenv`                            | `mise`                                                                |
| "Tuist Cloud"                         | shunchaki "Tuist" (server + dashboard, `tuist.dev`)                   |
| `.gitignore`: `Tuist/Dependencies/`   | `Tuist/.build`                                                        |
| `enforceExplicitDependencies: true`   | `tuist inspect dependencies --only implicit` (CI'da)                  |

> **💡 Pro tip:** To'g'ri (2026) `.gitignore` ning Tuist qismi — `tuist init` o'zi yaratgani (tekshirilgan):
>
> ```gitignore
> # .gitignore (Tuist qismi)
> *.xcodeproj
> *.xcworkspace
> graph.dot
> Derived/
> Tuist/.build
> ```
>
> Diqqat: endi `Tuist/Dependencies/` emas, `Tuist/.build` (tashqi paketlar shu yerga resolve bo'ladi). `xcuserdata/` va `DerivedData/` ni ham qo'shing.

---

## 10. Amaliy mashqlar {#mashqlar}

1. **O'rnatish va tekshirish.** `mise use tuist@4.211.1` (yoki Homebrew) bilan Tuist'ni o'rnating va `tuist version` chiqishi `4.211.1` ekanini tasdiqlang. Loyiha ildizida `mise.toml` paydo bo'lganini ko'ring.

2. **Konfliktni o'z ko'zingiz bilan ko'ring.** Yangi papka oching, `sources:` (not `buildableFolders:`) bilan bitta target'li loyiha yozing, `tuist generate` qiling, so'ng `.xcodeproj` ni **git'ga commit qiling**. Ikki branch oching, har birida bittadan `.swift` fayl qo'shib qayta generatsiya qiling, merge qiling va `project.pbxproj` da konflikt chiqishini kuzating. Keyin `.xcodeproj` ni `.gitignore` ga qo'shib, konflikt yo'qolishini ko'ring.

3. **Birinchi loyiha.** Ushbu darsdagi 2 modulli `SalomTuist` loyihasini noldan yozing, `tuist generate --no-open` qiling va o'zingizda generatsiya vaqtini o'lchang (`time tuist generate --no-open`). Mening natijam bilan solishtiring.

4. **Selective testing.** `tuist test Core --device "iPhone 17" --os 27.0` ni ikki marta ketma-ket ishga tushiring. Ikkinchi marta "no tests to run, finishing early" chiqishini va vaqt keskin qisqarishini kuzating. Keyin `Greeter.swift` ga bitta yangi test qo'shing va testlar yana ishga tushishini ko'ring.

5. **Grafik.** ⭐ `tuist graph --format svg --no-open` bilan grafik yarating (graphviz kerak: `brew install graphviz`) va `SalomApp → Core` bog'liqligini ko'ring. Keyin `Project.swift` ga yangi `Feature` target qo'shib, uni `SalomApp` ga bog'lang va grafik qanday o'zgarishini kuzating.

6. **`buildableFolders` tajribasi.** ⭐ `buildableFolders` ishlatadigan loyihada `project.pbxproj` ning md5'ini oling (`md5 *.xcodeproj/project.pbxproj`), yangi `.swift` fayl qo'shib qayta generatsiya qiling va md5 o'zgarmasligini tasdiqlang. Keyin `sources:` globga o'tkazib, xuddi shu tajribani takrorlang — bu safar o'zgaradi.

---

## 11. O'zingizni tekshiring {#checklist}

- [ ] `project.pbxproj` nima ekanini va u nega merge konflikt tug'dirishini tushuntira olaman.
- [ ] Nega generatsiyalangan loyihani Git'ga commit qilmaslik kerakligini bilaman.
- [ ] Tuist'ning ikki yuzini (generator CLI + platforma) ajrata olaman.
- [ ] "Implicit bog'liqlik" nima va "menikida ishlayapti" muammosi bilan qanday bog'liqligini bilaman.
- [ ] `mise` va Homebrew bilan Tuist o'rnata olaman va versiyani qotira olaman.
- [ ] `tuist init` → `tuist generate` → build → `tuist test` → `tuist graph` zanjirini bajara olaman.
- [ ] `tuist build` build buyrug'i emasligini va build `xcodebuild` bilan bo'lishini bilaman.
- [ ] Eski buyruqlarni (`tuist focus`, `tuist fetch`, `Config.swift`) 2026 ekvivalentlari bilan almashtira olaman.

---

## 12. Xulosa {#xulosa}

- **Muammo** — generatsiyalangan `project.pbxproj` ni Git'da saqlash: merge konfliktlar (biz haqiqiy konflikt ishlab chiqardik), inkonsistent setting'lar va yashirin (implicit) bog'liqliklar ("menikida ishlayapti").
- **Yechim** — Tuist loyihani Swift manifestlarda (`Project.swift`, `Tuist.swift`) ta'riflaydi, `tuist generate` esa `.xcodeproj`/`.xcworkspace` ni **hosila** sifatida yaratadi; hosila gitignore qilinadi, shuning uchun konflikt tug'ilmaydi.
- **Tuist 2026-da — ikki yuz:** bepul generator CLI (generate, graph, edit, migration, scaffold, inspect) + server/hisob bilan kuchayadigan platforma (module cache, selective testing, Xcode cache, insights, previews, registry, runners). Endi Bazel va Gradle'ni ham keshlaydi.
- **O'rnatish** — jamoa uchun `mise use tuist@4.211.1` (versiyani qotiring); yolg'iz ishlovchi uchun Homebrew. "latest" ga tayanmang.
- **O'z o'lchovlarim (M4 Pro):** generate 0.7 s; sovuq build 17.3 s; `tuist test` 25.1 s → takror 0.94 s (selective testing, hisobsiz); `buildableFolders` bilan fayl qo'shilsa pbxproj o'zgarmaydi.
- **Halol gap:** katta tezlik raqamlari vendor/mijoz manbalaridan, neytral benchmark yo'q. Kichik loyihada asosiy foyda — tartib va onboarding, tezlik esa miqyos oshgani sari.
- **Eskirganlardan qoching:** `tuist focus` → `tuist generate <Target>`, `tuist fetch` → `tuist install`, `Config.swift` → `Tuist.swift`, `tuist build <scheme>` endi build qilmaydi.

> **Keyingi dars:** [02. Manifest fayllar — Project.swift, Workspace.swift, Tuist.swift va Package.swift (2026 API)](/ios-lessons/tuist-02-manifest-fayllar) — har bir manifest faylni va `Target` ning barcha parametrlarini (haqiqiy `Target.swift` imzosi bo'yicha) sinchiklab ochamiz.

---

## 13. Manbalar {#manbalar}

1. [Tuist — Install Tuist (mise, Homebrew, versiyani qotirish)](https://tuist.dev/en/docs/guides/install-tuist)
2. [Tuist — The cost of convenience (implicit bog'liqliklar falsafasi)](https://tuist.dev/en/docs/guides/features/projects/cost-of-convenience)
3. [Tuist — Manifests (Tuist.swift, Project.swift)](https://tuist.dev/en/docs/guides/features/projects/manifests)
4. [Tuist — Migration from v3 to v4 (o'zgargan buyruqlar)](https://tuist.dev/en/docs/references/migrations/from-v3-to-v4)
5. [Tuist — Module cache va cache profillar (focus = all-possible)](https://tuist.dev/en/docs/guides/features/cache/module-cache)
6. [Tuist — Selective testing (faqat generatsiyalangan loyihalar)](https://tuist.dev/en/docs/guides/features/selective-testing)
7. [Tuist — Release channels (canary/RC/stable, dushanba promouti)](https://tuist.dev/en/docs/cli/release-channels)
8. [Tuist — Buildable folders (changelog, 2025-08-11)](https://tuist.dev/changelog/2025.08.11-buildable-folders)
9. [Tuist — Bazel'ni qo'llab-quvvatlash (blog, 2026-09-09)](https://tuist.dev/blog/2026/09/09/bazel)
10. [Monzo case study (Tuist, 2026-05-26)](https://tuist.dev/customers/monzo)
11. [Asana — Scaling a mature iOS codebase with Tuist (2023-02-21)](https://asana.com/inside-asana/scaling-a-mature-ios-codebase-with-tuist)
12. [Trendyol case study (Tuist blog, 2024-12-16)](https://tuist.dev/blog/2024/12/16/trendyol)
13. [monday.com case study (Tuist, 2025-12-15)](https://tuist.dev/customers/monday)
14. [Delivery Hero case study (Tuist, 2026-05-26)](https://tuist.dev/customers/delivery-hero)
15. [Toss case study (Tuist, 2026-10-01)](https://tuist.dev/customers/toss)
16. [Tuist GitHub Releases (versiya sanalari)](https://github.com/tuist/tuist/releases)
17. [Apple — Xcode 27 release notes (Swift 6.4, macOS Tahoe 26.6+)](https://developer.apple.com/documentation/xcode-release-notes/xcode-27-release-notes)
18. [mise — tool versiyalarini boshqarish](https://mise.jdx.dev)
