03. Directory Structure va CLI
🚀 Tuist — Mukammal Qo‘llanma & Amaliyot
Tuist 03: Papka tuzilmasi va CLI — har bir buyruq 2026 holatida, real natijalar bilan
Holat: 2026-yil oktabr. Bu dars Tuist loyihasining papka tuzilmasini (
Tuist.swift,Tuist/,Projects/,ProjectDescriptionHelpers/), nima commit qilinishi va nima generatsiya qilinishini, hamda Tuist CLI'ning har bir buyrug'ini real ishga tushirish bilan ko'rsatadi. Barcha kod va natijalar Tuist 4.211.1 va Xcode 27.1 bilan Apple M4 Pro'da tekshirilgan.
Bu darsdan keyin siz: bo'sh papkadan to'liq modulli Tuist loyihasini qura olasiz, har bir CLI buyrug'i nima qilishini va qachon kerakligini bilasiz,
.gitignore'ni to'g'ri yozib jamoada merge conflict'larni yo'qotasiz.
- Tavsiya etilgan papka tuzilmasini yod bilan emas, sababini tushungan holda qo'llaysiz.
tuist init'dantuist generate'gacha har bir buyruqni real natijasi bilan ko'rasiz.- Implicit va redundant dependency'larni
tuist inspect dependenciesbilan tutasiz (real xato + yechim). - Nima git'da saqlanadi, nima generatsiya qilinadi — chalkashlik qolmaydi.
- Tuist versiyasini jamoa uchun pin qilishni va
TUIST_*env'larni bilasiz.
Mundarija
- Nega papka tuzilmasi hal qiluvchi ahamiyatga ega
- Tavsiya etilgan papka tuzilmasi
- Har bir fayl va papka nima qiladi
- Nima commit qilinadi, nima generatsiya qilinadi
- [
tuist init— noldan loyiha](#tuist-init) - CLI xaritasi — buyruqlar ish bosqichi bo'yicha
- Kundalik oqim: install, generate, edit
- Ko'rish buyruqlari: graph va dump
- Tekshirish: inspect dependencies va hash
- Build va test: xcodebuild, tuist test, run
- Cache va tozalash: cache, clean
- Server buyruqlari (akkaunt kerak)
- Environment variable'lar va kataloglar
- Versiyani pin qilish (release channels)
- Real natijalar: o'lchangan vaqtlar
- Amaliy mashqlar
- O'zingizni tekshiring
- Xulosa
- Manbalar
1. Nega papka tuzilmasi hal qiluvchi ahamiyatga ega {#nega-struktura}
Xcode loyihasida papka tuzilmasi ikkinchi darajali masala — .xcodeproj ichida hamma narsa yashiringan va siz Xcode UI orqali fayl qo'shasiz. Tuist'da aksincha: papka tuzilmasi — bu loyihaning o'zi. Tuist .xcodeproj'ni har safar Swift manifest'lardan va diskdagi papkalardan qayta yasaydi. Shu sababli tuzilmani tushunmasdan Tuist'ni o'zlashtirib bo'lmaydi.
Bu nazariy gap emas. Asana muhandislik jamoasi (Mobile Foundations, 2023-yil 21-fevral) ~300 ming qator Swift kodini deyarli bitta target'da olib yurar edi. Ular Bazel'ni ham sinab ko'rishdi, lekin developer experience muammolari (og'ir sozlash, breakpoint'lar bilan nizolar) sababli Tuist'ni tanlashdi. Loyiha manifest'i ~1 400 qatorga yetdi; uni bir necha haftada yozishdi, so'ng kodni modullarga ko'chirish ~3 oy davom etdi. Natijada "o'zgartir va qayta qur" (change-and-rebuild) sikli odatdagi ~45 soniyadan ~15 soniyaga (median) tushdi.
🚀 Motivatsiya: Tuist papka tuzilmasi — bu shunchaki "chiroyli tartib" emas. To'g'ri tuzilma sizga uchta aniq narsani beradi: (1)
gitkonfliktlari deyarli yo'qoladi, chunki.xcodeprojendi git'da yo'q; (2) jamoadagi har bir developer bir xil loyihani ko'radi, chunki uni kod yasaydi; (3) modullarga bo'linish binary cache va selective testing uchun yo'l ochadi (keyingi darslarda o'lchab ko'rsatamiz). Asana'ning 45s → 15s siklini aynan shu tuzilma mumkin qildi.
⚠️ Diqqat: Asana o'z postida halol tan oladi — jamoaning faqat ozchiligi Tuist'ning ichki ishlashini chuqur tushunardi. Ya'ni tuzilma kuchli, lekin jamoaga uni o'rgatish kerak. Shuning uchun bu darsda biz "shunchaki nusxa ko'chir" demaymiz — har bir papka nega borligini tushuntiramiz.
Avvalgi darsda (02. Manifest fayllar) biz Project.swift, Workspace.swift, Tuist.swift va Package.swift sintaksisini o'rgandik. Endi bu fayllar diskda qayerda turishi va ularni CLI qanday topishini ko'ramiz.
2. Tavsiya etilgan papka tuzilmasi {#papka-tuzilmasi}
Tuist rasmiy hujjatidagi standart loyiha tuzilmasi quyidagicha ko'rinadi (manba: directory-structure):
Tuist.swift
Tuist/
Package.swift
ProjectDescriptionHelpers/
Projects/
App/
Project.swift
Feature/
Project.swift
Workspace.swift
Biz butun dars davomida shu tuzilmani real loyihada quramiz. "Kutubxona" degan oddiy ilova bo'ladi — kitoblar ro'yxati. Mana biz yaratgan va tekshirgan to'liq daraxt:
Kutubxona/
├── Tuist.swift ← root marker + global config
├── Tuist/
│ ├── Package.swift ← tashqi SPM dependency'lar
│ └── ProjectDescriptionHelpers/
│ └── Module.swift ← manifest'lar orasida shared kod
├── Workspace.swift ← bir nechta Project'ni birlashtiradi
├── Projects/
│ ├── App/
│ │ ├── Project.swift ← ilova (App target)
│ │ ├── Sources/
│ │ │ └── KutubxonaApp.swift
│ │ └── Resources/
│ ├── CoreKit/
│ │ ├── Project.swift ← domen modeli (static framework)
│ │ ├── Sources/
│ │ │ └── Book.swift
│ │ └── Tests/
│ │ └── LibraryTests.swift
│ └── Logger/
│ ├── Project.swift
│ ├── Sources/
│ └── Tests/
└── .gitignore
Ikkita asosiy qoida bu tuzilmani boshqaradi:
- **
Tuistpapkasi loyihaning ildizini (root) belgilaydi.** Tuist buyruqlarini loyihaning istalgan sub-papkasidan ishga tushirsangiz ham, Tuist yuqoriga qarabTuist/papkasini (yokiTuist.swift'ni) qidiradi va shuni ildiz deb biladi. Barcha nisbiy yo'llar shu ildizdan hisoblanadi. - **
Project.swiftyokiWorkspace.swift— loyihaga kirish nuqtasi.** Buyruqlar joriy papkada (yoki--pathbilan ko'rsatilgan papkada) shu fayllardan birini kutadi.
🧠 Esda tuting:
Tuist/papkasi (ichidaPackage.swiftyokiProjectDescriptionHelpers/bo'lgan) — bu kompas. SizProjects/App/ichida tursangiz ham,tuist generateyuqoriga qarab ildizni topadi. Agartuistni butunlay boshqa papkada ishga tushirsangiz, u "Tuist loyihasini topa olmadim" deydi — demak siz ildizdan tashqaridasiz.
💡 Pro tip: Xcode workspace'larni avval "merge conflict kamaysin" deb bir nechta
.xcodeproj'ga bo'lib ishlatishardi. Tuist'da bunga ehtiyoj yo'q — Tuist bittaProject.swift'dan ham avtomatik workspace yasaydi (loyiha + uning dependency'lari).Workspace.swift'ni faqat bir nechta mustaqil Project'ni qo'lda guruhlash kerak bo'lgandagina yozasiz (manba: directory-structure doc).
3. Har bir fayl va papka nima qiladi {#har-bir-fayl}
Tuist.swift — ildiz belgisi va global config
Loyihaning eng yuqori papkasida turadi va ikki vazifani bajaradi: (1) "loyiha shu yerdan boshlanadi" deb belgilaydi; (2) barcha loyihalar uchun umumiy sozlamalarni saqlaydi.
2026-yilda minimal Tuist.swift juda qisqa:
// Tuist.swift
import ProjectDescription
let tuist = Tuist(project: .tuist())
⚠️ Diqqat: Eski darsliklar va blog postlarida
Tuist.swiftichidagenerationOptions: .options(enforceExplicitDependencies: true)yozilgan. Tuist 4.211.1'da **enforceExplicitDependenciesdeprecated** — uning o'rninituist inspect dependenciesbuyrug'i egalladi (9-bo'limda ko'rasiz). Shuning uchun minimal konfiguratsiya endi faqatTuist(project: .tuist()). Agar eski loyihada u qolgan bo'lsa, ogohlantirish chiqadi.
Tuist/ papkasi
Ildiz ichidagi bu papka ikki narsani saqlaydi.
**1. Tuist/Package.swift — tashqi SPM dependency'lar.** Bu oddiy SPM Package.swift'dan farq qiladi: bu yerda faqat dependency'lar sanaladi, sizning target'laringiz emas. #if TUIST bloki esa Tuist'ga paketlarni qanday integratsiya qilishni aytadi:
// Tuist/Package.swift
// swift-tools-version: 6.0
import PackageDescription
#if TUIST
import struct ProjectDescription.PackageSettings
let packageSettings = PackageSettings(
// Mahsulot turini moslash mumkin. Default — .staticFramework
// productTypes: ["Alamofire": .framework]
productTypes: [:]
)
#endif
let package = Package(
name: "Kutubxona",
dependencies: [
// .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0"),
]
)
Bu aynan tuist init yasaydigan fayl (biz 5-bo'limda real ishga tushiramiz). Dependency'larni to'liq boshqarish keyingi darsda: 04. Dependency'lar.
**2. Tuist/ProjectDescriptionHelpers/ — manifest'lar orasidagi shared kod.** Bu papkadagi Swift fayllarni istalgan manifest import ProjectDescriptionHelpers bilan ishlatishi mumkin. Bu takrorlanishni kamaytiradi. Mana bizning helper — bitta framework modul + uning test target'ini yasaydigan factory:
// Tuist/ProjectDescriptionHelpers/Module.swift
import ProjectDescription
extension Project {
// Bitta framework modul + test target yaratadigan helper.
public static func module(
name: String,
dependencies: [TargetDependency] = []
) -> Project {
Project(
name: name,
targets: [
.target(
name: name,
destinations: .iOS,
product: .staticFramework,
bundleId: "uz.azimjondev.kutubxona.\(name.lowercased())",
deploymentTargets: .iOS("17.0"),
buildableFolders: ["Sources"],
dependencies: dependencies
),
.target(
name: "\(name)Tests",
destinations: .iOS,
product: .unitTests,
bundleId: "uz.azimjondev.kutubxona.\(name.lowercased())tests",
deploymentTargets: .iOS("17.0"),
buildableFolders: ["Tests"],
dependencies: [.target(name: name)]
),
]
)
}
}
Endi CoreKit moduli atigi uch qatorda ta'riflanadi:
// Projects/CoreKit/Project.swift
import ProjectDescription
import ProjectDescriptionHelpers
let project = Project.module(name: "CoreKit")
📊 Real raqamlar: Bu helper bir modulda ~30 qator
Project.swiftyozishni 3 qatorga tushiradi. 10 modulli loyihada bu ~300 qator o'rniga ~30 qator — va eng muhimi, barcha modullar bir xil qoidaga (bundleId formati, deployment target, test target) bo'ysunadi. Bu Asana'ning ~1 400 qatorli manifest'ini boshqarib bo'ladigan qilgan asosiy usul (manba: Asana eng blog).
🧠 Esda tuting: Eski oqimda
tuist installtashqi paketlarniTuist/Dependencies/papkasiga yuklardi. Tuist 4'da bu o'zgargan — paketlarTuist/.build/(SwiftPM'ning build papkasi) ichiga resolve bo'ladi. Shuning uchun.gitignore'gaTuist/.buildyoziladi,Tuist/Dependenciesemas.
Project.swift — Xcode project ta'rifi
Har bir Project.swift bitta Xcode project yasaydi. Loyiha nomi name property'dan olinadi. Bizning App loyihamiz CoreKit va Logger modullariga bog'lanadi:
// Projects/App/Project.swift
import ProjectDescription
let project = Project(
name: "App",
targets: [
.target(
name: "App",
destinations: .iOS,
product: .app,
bundleId: "uz.azimjondev.kutubxona",
deploymentTargets: .iOS("17.0"),
infoPlist: .extendingDefault(with: ["UILaunchScreen": [:]]),
buildableFolders: ["Sources", "Resources"],
dependencies: [
.project(target: "CoreKit", path: "../CoreKit"),
.project(target: "Logger", path: "../Logger"),
]
),
]
)
Bu yerda buildableFolders ishlatilgan — bu 2026-yilgi tavsiya etilgan yondashuv. sources: ["Sources/**"] glob'idan farqli o'laroq, buildableFolders papkani Xcode'ning "folder reference" sifatida qo'shadi: fayl qo'shganda yoki o'chirganda tuist generate'ni qayta ishga tushirish shart emas, va .pbxproj har bir fayl uchun o'zgarmaydi (manba: generated_app_with_buildable_folders fixture, Tuist repo).
Workspace.swift — bir nechta Project'ni birlashtirish
// Workspace.swift
import ProjectDescription
let workspace = Workspace(
name: "Kutubxona",
projects: ["Projects/App", "Projects/CoreKit", "Projects/Logger"]
)
Agar Workspace.swift bo'lmasa, tuist generate App'ning o'zidan va uning dependency'laridan avtomatik workspace yasaydi. Workspace.swift'ni faqat loyihalarni qo'lda guruhlash (yoki workspace'ga qo'shimcha fayl/scheme qo'shish) kerak bo'lganda yozasiz.
4. Nima commit qilinadi, nima generatsiya qilinadi {#commit-vs-generatsiya}
Bu — Tuist'dagi eng ko'p chalkashlik tug'diradigan nuqta. Qoidani bir marta tushunib oling: **manba (Swift manifest + kod) git'da; Xcode loyihalari esa generatsiya qilinadi va .gitignore'da.**
Chapda git'da saqlanadigan manba fayllar (Tuist.swift, Tuist/, Projects/, Workspace.swift, .gitignore), o'ngda tuist generate yasaydigan va gitignore qilinadigan fayllar (.xcworkspace, .xcodeproj, Derived/, Tuist/.build)
Chap panelda — git'da saqlanadigan yagona narsalar: Swift manifest'lar, helper'lar va sizning kodingiz. O'ng panelda — tuist generate har safar qayta yasaydigan va shuning uchun .gitignore'ga tushadigan fayllar.
tuist init loyiha bilan birga .gitignore ham yasaydi. Mana uning Tuist'ga tegishli oxirgi qismi (real, tuist init chiqargani):
### Projects ###
*.xcodeproj
*.xcworkspace
### Tuist derived files ###
graph.dot
Derived/
### Tuist managed dependencies ###
Tuist/.build
⚠️ Diqqat:
.xcodeprojva.xcworkspace'ni git'ga qo'shmang. Agar qo'shsangiz, ikki muammo paydo bo'ladi: (1) har bir developertuist generateishga tushirganda ming qatorli.pbxprojdiff'i chiqadi va har PR'da merge conflict beradi — bu aynan Tuist hal qilmoqchi bo'lgan muammo; (2) generatsiya natijasi mashinaga bog'liq (yo'llar absolyut bo'lishi mumkin), shuning uchun uni commit qilish ma'nosiz. Bitta istisno: agar siz Tuist'ni mavjud Xcode loyiha ustiga qo'shayotgan bo'lsangiz (migration), o'sha paytda.xcodeprojhali git'da bo'ladi — buni 05. Migratsiya darsida ko'ramiz.
🧠 Esda tuting: Loyihani clone qilgan yangi developer uchun ishga tushirish ketma-ketligi:
tuist install(paketlarni oladi) →tuist generate(Xcode loyihani yasaydi) → Xcode'da ishlang..xcodeprojgit'da bo'lmagani — bu kamchilik emas, balki dizayn: har kim bir xil, toza loyihani oladi.
5. tuist init — noldan loyiha {#tuist-init}
Tuist 4.211.1'da tuist init endi interaktiv sehrgar (wizard) sifatida ishlaydi va to'rt turdagi integratsiyani taklif qiladi: xcode (mavjud Xcode loyihaga ulanish), generated-xcode (yangi Tuist-generated loyiha), gradle, bazel. Barcha so'rovlarni flag'lar bilan oldindan javoblab, non-interaktiv ishga tushirsangiz ham bo'ladi:
# Yangi, Tuist generatsiya qiladigan iOS loyiha; serversiz (akkaunt shart emas)
tuist init --build-system generated-xcode --platform ios --name Demo --no-server
Natija (real, qisqartirilgan):
ℹ︎ Creating generated project
✔︎ Generated project created [0.1s]
✔ Success
You are all set to explore the Tuist universe
Takeaways:
▸ Choose the project directory with 'cd Demo'
▸ Generate your project with 'tuist generate'
▸ Visualize your project graph with 'tuist graph'
tuist init quyidagi fayllarni yasaydi (biz yuqorida qo'lda qurgan tuzilmaning aynan o'zi): Tuist.swift, Tuist/Package.swift, Project.swift, Demo/Sources/{DemoApp.swift, ContentView.swift}, Demo/Tests/DemoTests.swift, Demo/Resources/Assets.xcassets/... va .gitignore.
Muhim: yasalgan Project.swift ham **buildableFolders** ishlatadi va yasalgan Tuist.swift ham minimal — bu 2026-yilgi standart ekanini tasdiqlaydi:
// tuist init yasagan Project.swift (qisqartirilgan)
.target(
name: "Demo",
destinations: .iOS,
product: .app,
bundleId: "dev.tuist.Demo",
infoPlist: .extendingDefault(with: ["UILaunchScreen": [...]]),
buildableFolders: ["Demo/Sources", "Demo/Resources"],
dependencies: []
)
💡 Pro tip:
--no-serverflag'i muhim. Default holatdatuist initTuist serveriga ulanmoqchi bo'ladi (cache va insights uchun), bu esa akkaunt talab qiladi. O'rganish bosqichida yoki akkauntsiz ishlashda doim--no-serverqo'shing. Akkaunt kerak bo'ladigan funksiyalarni 12-bo'limda ajratib ko'rsatamiz.
⚠️ Diqqat:
tuist initloyihani joriy papka nomidan oladi (--nameberilmasa). Shuning uchun uni to'g'ri nomli bo'sh papka ichida ishga tushiring, aks holda papka nomi loyiha nomiga aylanadi.
6. CLI xaritasi — buyruqlar ish bosqichi bo'yicha {#cli-xaritasi}
tuist --help 25+ buyruqni ko'rsatadi — bu dastlab qo'rqitadi. Lekin ularni ish bosqichi bo'yicha guruhlasangiz, manzara soddalashadi. Quyidagi xarita barcha asosiy buyruqlarni to'rt toifaga ajratadi:
Tuist CLI buyruqlari xaritasi: yuqorida kundalik oqim (init, install, generate, Xcode build/run, test), pastda to'rt panel — ko'rish (graph, dump), tekshirish (inspect, hash, migration), cache va tozalash (cache, clean, scaffold), server/akkaunt (auth, share, registry, account)
Yuqori qator — kundalik oqim: bu buyruqlarni har kuni ishlatasiz. Pastdagi to'rt panel — yordamchi buyruqlar: kerak bo'lganda chaqirasiz. Qulf belgisi (🔒) Tuist akkaunti talab qiladigan buyruqlarni bildiradi.
To'liq ro'yxatni ko'rish uchun:
tuist --help
Natija (real, qisqartirilgan — toifalar bo'yicha):
GET STARTED SUBCOMMANDS:
init Get started with Tuist in your project.
DEVELOP SUBCOMMANDS:
hash Utilities to debug the hashing logic ...
build A set of commands to manage your project builds.
cache Cache-related commands.
clean Clean all the artifacts stored locally
dump Outputs the manifest as a JSON
edit Generates a temporary project to edit the project ...
generate Generate a project or inspect generation runs.
graph Generates a graph from the workspace or project ...
install Installs any remote content (e.g. dependencies) ...
migration A set of utilities to assist in the migration ...
run Runs a preview or a scheme from a generated project.
scaffold Generates new project based on a template
test Tests a project
inspect Inspect your project to identify issues ...
xcodebuild tuist xcodebuild extends the xcodebuild CLI ...
SHARE SUBCOMMANDS:
share Generate a link to share your app.
ACCOUNT SUBCOMMANDS:
account, project, bundle, organization, auth
🧠 Esda tuting:
buildbuyrug'i nomi aldamchi — bu build qiluvchi buyruq emas. 4.211'datuist buildfaqat build yozuvlarini (records) ko'rsatadi (list,show,xcode,gradle). Haqiqiy build'ni Xcode qiladi (tuist generate→ Cmd+R) yokixcodebuild/tuist xcodebuild build(insights bilan). Eskituist build <scheme>olib tashlangan.
7. Kundalik oqim: install, generate, edit {#kundalik-oqim}
tuist install — paketlarni olish
Tuist/Package.swift'dagi tashqi SPM dependency'larni resolve va yuklab oladi. Bizning loyihada tashqi paket yo'q, shuning uchun u faqat plugin'larni tekshiradi:
tuist install
Resolving and fetching plugins.
Resolving and fetching dependencies.
✔ Success
Plugins resolved and fetched successfully.
Qachon ishlatasiz: loyihani birinchi marta clone qilganda, yangi paket qo'shganda yoki versiyasini o'zgartirganda. tuist install --update esa paketlarni yangi versiyalarga ko'taradi.
tuist generate — Xcode loyihani yasash
Eng ko'p ishlatiladigan buyruq. Manifest'lardan .xcworkspace va .xcodeproj yasaydi va Xcode'da ochadi:
# --no-open: Xcode'ni avtomatik ochmaslik (CI va o'lchov uchun qulay)
tuist generate --no-open
Loading and constructing the graph
It might take a while if the cache is empty
Using cache binaries for the following targets:
Generating workspace Kutubxona.xcworkspace
Generating project App
Generating project CoreKit
Generating project Logger
Total time taken: 1.611s
✔ Success
Project generated.
Yasalgan fayllar: ildizda Kutubxona.xcworkspace, har bir loyiha papkasida <Nom>.xcodeproj va Derived/.
Fokuslangan generatsiya (focused generation). Katta loyihada hamma narsani ochish shart emas. Bitta (yoki bir nechta) target'ga fokuslansangiz, qolganlari (agar binary cache bor bo'lsa) manba o'rniga binary sifatida ulanadi:
# Faqat App'ga fokus
tuist generate App --no-open
# Tag bo'yicha fokus (metadata tag'lari 16-darsda)
tuist generate tag:feature --no-open
⚠️ Diqqat: Eski
tuist focusbuyrug'i olib tashlangan — uning o'rnigatuist generate <target>ishlatiladi. Muhim nuance: fokus faqat binary cache bo'lganda tezlashtiradi. Agar cache bo'sh bo'lsa,tuist generate Appbaribir CoreKit va Logger'ni manba sifatida yasaydi (bizning o'lchovda fokus va to'liq generatsiya ikkalasi ham ~0.55s bo'ldi — chunki cache bo'sh edi). Binary cache bilan real tezlanishni 07. Cache va 11. E-Commerce darslarida o'lchaymiz.
Cache profili. tuist generate'ning binary cache'dan qanday foydalanishini --cache-profile boshqaradi:
tuist generate --cache-profile only-external # faqat tashqi paketlar (default)
tuist generate --cache-profile all-possible # imkon qadar ko'proq target binary
tuist generate --cache-profile none # hammasi manbadan
tuist generate --no-binary-cache # cache'ni butunlay e'tiborsiz qoldirish
--help'dan to'g'ridan-to'g'ri: profil berilmasa, Tuist.swift'dagi sozlama ishlaydi, u ham bo'lmasa only-external.
Generatsiya tarixini ko'rish (akkaunt kerak). tuist generate list / show — bu server funksiyasi:
tuist generate list
✖ Error
We couldn't list generations because the full handle is missing. You can pass
either its value or a path to a Tuist project.
Ya'ni generate list/show faqat loyiha Tuist serveriga ulangan bo'lsa ishlaydi. Lokal tuist generate run (default subcommand) esa doim ishlaydi.
tuist edit — manifest'larni Xcode'da tahrirlash
Manifest'lar oddiy Swift kod, lekin ularni to'g'ridan-to'g'ri yasalgan loyihadan tahrirlab bo'lmaydi (bu ataylab shunday — yasalgan loyiha Tuist'ga bog'liq bo'lib qolmasligi uchun). tuist edit maxsus vaqtinchalik Xcode project ochadi, unda autocomplete, syntax highlighting va kompilyatsiya tekshiruvi ishlaydi:
tuist edit
Bu buyruq Xcode'ni ochib, jarayonni bloklaydi (siz tahrirni tugatib Xcode'ni yopguningizcha kutadi). Shuning uchun uni CI'da yoki fon rejimida ishlatmang. Oqim: tuist edit → Xcode'da Project.swift'ni o'zgartiring → Xcode'ni yoping → tuist generate.
💡 Pro tip:
tuist edit --permanentdoimiy edit-project'ni joriy papkada yasaydi va jarayonni bloklamaydi — buni skriptlarda qulay.tuist edit --only-current-directoryesa faqat joriy papkadagi manifest'ni qo'shadi (katta loyihada edit-project tez ochilishi uchun).
8. Ko'rish buyruqlari: graph va dump {#korish-buyruqlari}
tuist graph — dependency grafini ko'rish
Loyihadagi target'lar va ularning bog'liqliklarini vizual yoki matn ko'rinishida chiqaradi. Formatlar: dot, json, png, svg (png/svg uchun tizimda dot/graphviz kerak):
# PNG o'rniga dot (matn) — graphviz'siz ham ishlaydi, git'da diff qilsa bo'ladi
tuist graph --format dot --no-open
Yasalgan graph.dot (real, bizning 3 modulli loyiha uchun):
digraph {
App [fillcolor=deepskyblue penwidth="1.5" shape=box3d style=filled]
CoreKit [fillcolor=coral1 shape=cylinder style=filled]
CoreKitTests [fillcolor=limegreen shape=octagon style=filled]
App -> CoreKit
CoreKitTests -> CoreKit
}
Grafni o'qish: App → CoreKit (ilova domen modeliga bog'langan), CoreKitTests → CoreKit (test o'z modulini sinaydi). Shakllar turini bildiradi: box3d — ilova, cylinder — framework, octagon — test.
Foydali flag'lar (--help'dan): --skip-test-targets (test'larsiz toza graf), --skip-external-dependencies (tashqi paketlarsiz), --platform ios, va <targets> — faqat ko'rsatilgan target'lar va ularga bog'liqlarini chizadi.
💡 Pro tip:
tuist graph --format dot'ni CI'da saqlab, PR'larda diff qiling — kimdir keraksiz yangi dependency qo'shsa,graph.dotdiff'ida darhol ko'rinadi. Bu arxitekturani "lint" qilishning arzon usuli. (Lekingraph.dot'ni.gitignore'dan chiqarib qo'yishni unutmang —tuist inituni default ignore qiladi.)
tuist dump — manifest'ni JSON sifatida chiqarish
Manifest Swift kodini Tuist qanday "ko'rishini" JSON'da ko'rsatadi. Debug va skriptlar uchun foydali:
tuist dump project --path Projects/App
{
"additionalFiles": [
],
"name": "App",
...
}
<manifest> argumenti project (default), workspace, config, template, plugin yoki package bo'lishi mumkin.
9. Tekshirish: inspect dependencies va hash {#tekshirish}
tuist inspect dependencies — implicit va redundant bog'liqliklarni tutish
Bu — enforceExplicitDependencies'ning o'rnini bosgan buyruq va Tuist'ning eng kuchli "arxitektura linter"laridan biri. U ikki muammoni topadi:
- Implicit dependency: target biror modulni
importqiladi, lekin uni dependency sifatida e'lon qilmagan. Kod kompilyatsiya bo'lishi mumkin (chunki modul grafda boshqa yo'l orqali ko'rinadi), ammo bog'liqlik yashirin — ertaga grafni o'zgartirsangiz, kutilmaganda buziladi. - Redundant dependency: target modulni dependency sifatida e'lon qilgan, lekin uni hech qayerda
importqilmaydi — keraksiz bog'liqlik.
Keling, buni ataylab buzib ko'rsatamiz. Faraz qiling, App kodida Logger'ni ishlatamiz, lekin Project.swift'da uni e'lon qilishni unutamiz; va CoreKit esa Logger'ni e'lon qiladi-yu, aslida ishlatmaydi:
// Projects/App/Sources/KutubxonaApp.swift
import CoreKit
import Logger // ← ishlatamiz, lekin Project.swift'da e'lon qilinmagan!
func bootLog() { Logger.log("ilova ishga tushdi") }
tuist inspect dependencies
Natija (real xato — ikkala muammoni ham tutdi):
Loading and constructing the graph
It might take a while if the cache is empty
✖ Error
The following implicit dependencies were found:
- App implicitly depends on: Logger
The following redundant dependencies were found:
- CoreKit redundantly depends on: Logger
Bitta buyruq ikkala kasallikni ham ko'rsatdi: App yashirin ravishda Logger'ga bog'liq, CoreKit esa Logger'ni behuda e'lon qilgan. Buyruq muammo topilsa 1 bilan chiqadi (exit code), shuning uchun uni CI'da to'siq (gate) sifatida ishlatsa bo'ladi.
Faqat bitta tekshiruvni ishlatish mumkin:
tuist inspect dependencies --only implicit # faqat implicit
tuist inspect dependencies --only redundant # faqat redundant
The following implicit dependencies were found:
- App implicitly depends on: Logger
Yechim. App endi Logger'ni ochiq e'lon qiladi, CoreKit esa keraksiz e'londan xalos bo'ladi:
// Projects/App/Project.swift — App endi Logger'ni ochiq e'lon qiladi
dependencies: [
.project(target: "CoreKit", path: "../CoreKit"),
.project(target: "Logger", path: "../Logger"),
]
// Projects/CoreKit/Project.swift — Logger'ni olib tashladik (ishlatilmaydi)
let project = Project.module(name: "CoreKit")
Qayta generatsiya va tekshiruv:
tuist generate --no-open && tuist inspect dependencies
We did not find any dependency issues in your project (checked: implicit, redundant).
Exit code endi 0 — graf toza.
🧠 Esda tuting:
tuist inspect dependencies— bu implicit import muammosini ushlaydigan asosiy vosita. EskienforceExplicitDependenciesgeneratsiya paytida xato berardi; yangi yondashuv esa alohida buyruq bo'lgani uchun CI'da moslashuvchan (siz qaysi tekshiruvni qachon ishga tushirishni hal qilasiz). Implicit dependency'ning chuqur mexanikasi va ko'proq misollar — 04. Dependency'lar darsida.
⚠️ Diqqat:
--output summaryva--jsonformatlari--help'da bor, lekin 4.211.1'da muammo topilgan holatda ular standart chiqishga topilmalarni yozmaydi (faqat exit code'ni qaytaradi). Shuning uchun odam o'qiydigan natija uchun defaulttextformatidan foydalaning; CI'da esa exit code'ga tayaning.
tuist hash — cache va selective testing hash'larini ko'rish
Tuist binary cache va selective testing uchun har bir target'ni hash qiladi (fayllar, sozlamalar, dependency'lar asosida). tuist hash bu hash'larni ko'rsatadi — debug uchun:
tuist hash cache
Loading and constructing the graph
It might take a while if the cache is empty
CoreKit - fb8a606dbf4388b778d6c60d94b04207
Faqat cache qilsa bo'ladigan target'lar (framework'lar) ko'rsatiladi — App (ilova) va test target'lari bu ro'yxatda yo'q.
Selective testing uchun hash'lar alohida:
tuist hash selective-testing
CoreKit - e07a49c190f8eae3553f13641c362a14
CoreKitTests - e1a4d0c0d13137fe137e6f3ed55973a1
💡 Pro tip: Bir fayl o'zgarsa, faqat o'sha target'ning (va unga bog'liqlarning) hash'i o'zgaradi — shuning uchun cache qolgan hammasini qayta ishlatadi. Agar "nega cache miss bo'ldi?" degan savol tug'ilsa,
tuist hash cache'ni o'zgarishdan oldin va keyin solishtiring. Hashing'ning ichki mexanikasi 07. Cache darsida.
10. Build va test: xcodebuild, tuist test, run {#build-test}
Build qilish
Yuqorida aytganimizdek, Tuist 4'da tuist build endi build qilmaydi. Loyihani ikki yo'l bilan quriladi:
1. Xcode orqali (kundalik ish): tuist generate → Xcode ochiladi → Cmd+R.
**2. Terminaldan xcodebuild bilan** (CI uchun). Yasalgan workspace oddiy Xcode workspace, shuning uchun to'g'ridan-to'g'ri xcodebuild ishlaydi:
tuist generate --no-open
xcodebuild -workspace Kutubxona.xcworkspace -scheme App \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath .dd build
Bizning loyihada bu natija bilan tugadi (real):
** BUILD SUCCEEDED **
Ya'ni 3 modulli (App → CoreKit, App → Logger) buildableFolders'li tuzilma Xcode 27.1'da muammosiz kompilyatsiya bo'ldi.
💡 Pro tip: Insights (build analytics) kerak bo'lsa,
xcodebuildo'rnigatuist xcodebuild build ...ishlating — u aynanxcodebuild'ni o'raydi, lekin build ma'lumotlarini Tuist serveriga yuboradi (akkaunt kerak).tuist xcodebuildsubkomandalar:build,test,build-for-testing,test-without-building,archive.
🧠 Esda tuting: CI'da yoki o'lchovda doim o'z work-dir'ingiz ichida
-derivedDataPathbering (.ddkabi). Shunda DerivedData loyihaga yopishib qolmaydi va boshqa loyihalar bilan aralashmaydi.
tuist test — selective testing bilan
tuist test test scheme'larini topib ishga tushiradi, lekin eng qimmatli xususiyati — selective testing: o'tgan safardan beri o'zgarmagan target'lar testini qayta o'tkazmaydi (lokal, akkauntsiz ishlaydi).
# Simulyatorni ro'yxatdan tanlang: xcrun simctl list devices available
tuist test CoreKit --device "iPhone 17" --os 27.0
FACTS.md'da bu mashinada (Apple M4 Pro, Xcode 27.1, Tuist 4.211.1) tasdiqlangan xatti-harakat: shunga o'xshash modulli loyihada birinchi tuist test ~26 soniyada o'tdi, ikkinchi marta esa ~1 soniya:
The scheme Core's test action has no tests to run, finishing early.
Ya'ni kod o'zgarmagani uchun Tuist test'ni o'tkazib yubordi. Selective testing'ni o'chirish uchun --no-selective-testing.
⚠️ Diqqat: Ikki nozik nuqta. (1) Selective testing faqat generated loyihalar uchun (
tuist test).tuist xcodebuild testesa insights, sharding va quarantine beradi, lekin 4.211.1'da selective testing emas. (2) Simulyator nomi aniq mavjud bo'lishi kerak — FACTS.md'da--device "iPhone 17 Pro""Could not find a suitable device" bilan yiqildi, chunki o'sha nomli simulyator yo'q edi. Doimxcrun simctl list devices availablebilan tekshiring. Selective testing'ni 09. ToDo App loyihasida o'lchab ko'rsatamiz.
tuist run — scheme yoki preview'ni ishga tushirish
tuist run yasalgan loyihadan scheme'ni (yoki serverdagi preview'ni) build qilib, simulyatorda ishga tushiradi:
tuist run App --device "iPhone 17" --os 27.0
App@latest, App@feature-branch yoki App@<sha> ko'rinishidagi preview specifier'lari Tuist serveridagi preview'ni ishga tushiradi (akkaunt kerak) — buni 15. Tuist platformasi darsida ko'ramiz.
11. Cache va tozalash: cache, clean {#cache-tozalash}
tuist cache — binary cache
Modullarni oldindan kompilyatsiya qilib, .xcframework sifatida saqlaydi — keyin tuist generate ularni manba o'rniga tayyor binary bilan almashtiradi. Lokal cache akkauntsiz ishlaydi:
# Lokal cache'ni "isitish", serverga yuklamasdan
tuist cache warm --no-upload
FACTS.md'da tasdiqlangan: bu buyruq CoreKit'ni qurib ~/.cache/tuist/Binaries/<hash>/CoreKit.xcframework ga saqlaydi va xulosa chiqaradi:
Cache warm summary: 0 remote hits, 0 local hits, 1 misses
So'ng tuist generate --cache-profile all-possible "Using cache binaries for the following targets: CoreKit" deb yozadi va loyiha binary'dan foydalanadi. Cache'ning to'liq mexanikasi, profillari va o'lchangan tezlanishi — 07. Cache.
⚠️ Diqqat:
tuist cachesubkomandalari —warm(default) vaconfig. Eski--external-onlyflag'i deprecated bo'ldi; uning o'rniga--cache-profile only-externalishlating. Remote cache (jamoa orasida ulashiladigan) Tuist akkaunti va rejasini talab qiladi; lokal cache esa bepul.
tuist clean — lokal artefaktlarni tozalash
"Tushunarsiz xato" chiqqanda yoki cache eskirganda ishlatasiz. Diqqat qiling — tuist clean aniq toifalarni oladi:
tuist clean # hammasini tozalaydi
tuist clean manifests projectDescriptionHelpers # faqat manifest cache
tuist clean binaries # faqat binary cache
--help ko'rsatadigan to'liq toifalar ro'yxati: plugins, generatedAutomationProjects, projectDescriptionHelpers, manifests, editProjects, runs, binaries, selectiveTests, generationMetadata, dependencies. --remote esa remote cache'ni tozalaydi (akkaunt kerak).
💡 Pro tip: Butun loyihani emas, aniq muammoni tozalang. Manifest o'zgarishi "yopishib qolgan" bo'lsa —
tuist clean manifests projectDescriptionHelpers. Binary cache shubhali bo'lsa —tuist clean binaries. Bu to'liqtuist clean'dan ancha tez (keyingi generatsiya hamma narsani qayta kompilyatsiya qilmaydi).
tuist scaffold — template'dan kod yasash
Loyihada aniqlangan template'lardan (masalan, yangi µFeature skeleti) kod yasaydi:
tuist scaffold list # mavjud template'lar
tuist scaffold <template> --name MyFeature
Template'lar, plugin'lar va ProjectDescriptionHelpers'ni chuqur o'rganish — 08. Kodni qayta ishlatish.
12. Server buyruqlari (akkaunt kerak) {#server-buyruqlari}
Quyidagi buyruqlar Tuist serveriga (tuist.dev) ulanishni talab qiladi. Ularni ro'yxatlab, nima qilishini bilib qo'yish foydali, lekin ishlatish uchun akkaunt kerak. Barchasi --help orqali tekshirildi.
| Buyruq | Nima qiladi | Akkaunt |
|---|---|---|
tuist auth login / logout / whoami | Tuist serveriga kirish / chiqish | ✅ kerak |
tuist share | Ilovadan ulashiladigan preview havolasi yasaydi | ✅ kerak |
tuist registry setup / login | Swift Package Registry orqali tez resolve | ✅ kerak |
tuist account / project / organization / bundle | Akkaunt, loyiha, tashkilot va bundle boshqaruvi | ✅ kerak |
tuist runner ssh / volume | CI runner'lari bilan ishlash | ✅ kerak |
tuist setup cache / insights | Xcode compilation cache va insights daemon sozlash | qisman |
# Kirish (brauzer ochiladi)
tuist auth login
# Kim kirgan?
tuist auth whoami
🧠 Esda tuting:
tuist registry— bu dependency'larni tezroq resolve qilish uchun (Swift Package Registry protokoli orqali).tuist shareesa build qilingan ilovani boshqalarga havola orqali ko'rsatish (preview). Ikkalasi ham Tuist akkaunti talab qiladi. Narx rejalar (2026-10 holatida): Air (bepul, karta kerak emas, barcha funksiyalar bepul limit ichida), Pro (limitdan oshsa to'lov), Enterprise (self-hosting, korxona uchun). Open source loyihalar uchun bepul. To'liq platforma — 15. Tuist platformasi.
💡 Pro tip:
tuist setup cacheqisman mahalliy ishlaydi — u Xcode'ning compilation cache'ini (LLVM CAS) proxy orqali ulaydi. Lekin remote cache'dan to'liq foyda olish uchun server kerak. Bu — Bazel'ning remote action cache'iga o'xshash, lekin Xcode'ning o'z build tizimi ustida. Taqqoslash 14. Best practices va Bazel moduli (bazel-01-kirish...) da.
tuist migration — mavjud Xcode loyihasidan ko'chirish
Serverga bog'liq emas; mavjud .xcodeproj'dan Tuist'ga o'tishga yordam beradi:
tuist migration settings-to-xcconfig -p App.xcodeproj -x App.xcconfig
tuist migration list-targets -p App.xcodeproj
tuist migration check-empty-settings -p App.xcodeproj
To'liq migratsiya oqimi — 05. Migratsiya.
13. Environment variable'lar va kataloglar {#env-kataloglar}
TUIST_* env'lar — har bir flag'ni avtomatlashtirish
Tuist'ning deyarli har bir flag'ini environment variable orqali ham berish mumkin — bu CI'da qulay. --help chiqishi har bir flag yonida mos env nomini ko'rsatadi, masalan:
-o, --open/--no-open ... (env: TUIST_GENERATE_OPEN) (default: --open)
--cache-profile ... ... (env: TUIST_GENERATE_CACHE_PROFILE)
Shunday qilib CI'da flag yozish o'rniga:
export TUIST_GENERATE_OPEN=0 # --no-open bilan bir xil
export TUIST_GENERATE_CACHE_PROFILE=all-possible
tuist generate
Tuist kataloglari (XDG)
Tuist o'z fayllarini XDG standartiga ko'ra uchta katalogda saqlaydi (manba: cli/directories):
| Katalog | Default | Nima saqlanadi |
|---|---|---|
| Config | ~/.config/tuist | Server credential'lari |
| Cache | ~/.cache/tuist | Binaries, Manifests, ProjectDescriptionHelpers, Plugins, SelectiveTests, Runs |
| State | ~/.local/state/tuist | Sessiya loglari (sessions/<uuid>/), lock'lar |
Har birini TUIST_XDG_* (ustunlik) yoki standart XDG_* bilan o'zgartirish mumkin. Bu CI'da yoki loyihani izolyatsiya qilishda juda foydali:
# CI'da vaqtinchalik kataloglar
export TUIST_XDG_CACHE_HOME=/tmp/tuist-cache
export TUIST_XDG_STATE_HOME=/tmp/tuist-state
tuist generate
💡 Pro tip: Biror buyruq g'alati xato bersa, log fayliga qarang — Tuist har sessiyada yo'lni ko'rsatadi:
~/.local/state/tuist/sessions/<uuid>/logs.txt. Biztuist generate listxatosida aynan shu havolani ko'rdik. Bu birinchi debug qadami.
🧠 Esda tuting:
~/.cache/tuist/Binaries— binary cache shu yerda. "Cache'ni to'liq tozalamoqchiman" desangiz,tuist clean binariesyoki bu papkani o'chirish kifoya — loyihangizga tegmaydi. Bu Bazel'ning~/Library/Caches/bazeloutput base'iga o'xshash g'oya: artefaktlar loyihadan tashqarida, markaziy joyda.
14. Versiyani pin qilish (release channels) {#versiya-pin}
Jamoada eng ko'p uchraydigan muammo — turli developerlarda turli Tuist versiyasi. Bir kishida tuist generate ishlaydi, boshqasida xato — chunki manifest API versiyaga bog'liq. Yechim: versiyani pin qilish.
Tuist uchta kanal orqali tarqaladi (manba: release-channels):
| Kanal | Format | Qachon chiqadi | Default? |
|---|---|---|---|
| Canary | X.Y.0-canary.N | Har commit (main'ga) | Yo'q |
| Release candidate | X.Y.0-rc.N | Har dushanba, ~1 hafta sinaladi | Yo'q |
| Stable | X.Y.Z | RC toza o'tgach, dushanbada | ✅ Ha |
Mise (tavsiya etilgan) bilan pin qilish:
mise use tuist@4.211.1 # aniq versiyaga pin (eng barqaror)
mise use tuist@4.211 # stable liniyaga pin (faqat backport fix'lar)
mise use tuist@latest # oxirgi stable
Mise loyiha papkasiga mise.toml yozadi; jamoadoshingiz mise install bilan aynan o'sha versiyani oladi. Homebrew ham ishlaydi, lekin u faqat global versiyani boshqaradi:
brew tap tuist/tuist
brew install --formula tuist # oxirgi stable
brew install --formula tuist@x.y.z # aniq versiya
🧠 Esda tuting: Bu darsdagi hamma narsa Tuist 4.211.1 bilan tekshirilgan (Homebrew cask orqali o'rnatilgan).
tuist@latestfaqat stable'ni oladi — canary va RC'lar hech qachonlatest'ga tushmaydi, ularga faqat ataylab o'tiladi. Tavsiya: stable liniyaga pin qiling (masalantuist@4.211), yangi minor'ga esa RC'da sinab ko'rgach o'ting. Tuist 5 hali yo'q.
⚠️ Diqqat: Tuist versiyasini
mise.toml'da pin qilib, uni git'ga commit qiling — bu.gitignore'dagi generatsiya fayllaridan farqli o'laroq, manba konfiguratsiyaning bir qismi. Shunda CI va har bir developer bir xil Tuist ishlatadi.
15. Real natijalar: o'lchangan vaqtlar {#real-natijalar}
Quyidagi vaqtlar bizning 3 modulli Kutubxona loyihasida (App → CoreKit, App → Logger) Apple M4 Pro (12 yadro, 24 GB), Xcode 27.1, Tuist 4.211.1 da o'lchandi. Timing o'lchovlari eksklyuziv build-slot lock ostida olingan (boshqa jarayonlar aralashmasligi uchun).
| Buyruq | Shart | Vaqt |
|---|---|---|
tuist generate --no-open | to'liq, 3 modul, manifest cache iliq | ~0.55 s |
tuist generate --no-open | tuist clean manifests'dan keyin (cold) | 1.32 s |
tuist generate App --no-open | fokus, binary cache yo'q | ~0.55 s |
tuist graph --format dot --no-open | dot eksport | 0.32 s |
xcodebuild ... -scheme App build | 3 modul, cold | ** BUILD SUCCEEDED ** |
📊 Real raqamlar: Uchta xulosa. (1)
tuist generatearzon — iliq manifest cache bilan ~0.55 s. Shuning uchun undan qo'rqmang: har safargit pull'dan keyin bemalol ishga tushiring. (2) "Cold" (manifest cache tozalangan) holat ikki baravar sekinroq — ~1.32 s — chunki Tuist manifest'larni va helper'larni qaytadan kompilyatsiya qiladi. (3) Fokus bu loyihada tezlashtirmadi (~0.55 s ikkalasida) — chunki binary cache bo'sh edi, shuning uchun CoreKit va Logger baribir manbadan yasaldi. Fokus faqat binary cache bilan birga ma'no kasb etadi; buni 07. Cache va 11. E-Commerce da katta loyihada o'lchaymiz.
🚀 Motivatsiya: 0.55 soniyalik generatsiya — bu sizning kundalik tsiklingiz deyarli "bepul" degani. Asana'da 45s → 15s (change-and-rebuild) tejamkorlik aynan shu modulli tuzilma + binary cache'dan keldi. Bu darsda siz tuzilmani qurdingiz; keyingi darslarda cache'ni qo'shib, o'sha tejamkorlikni o'z loyihangizda o'lchaysiz.
Amaliy mashqlar {#mashqlar}
- Noldan loyiha. Bo'sh papka yarating va
tuist init --build-system generated-xcode --platform ios --name Mashq --no-serverbilan loyiha yasang. Yasalgan.gitignore'daTuist/.buildvaDerived/borligini tekshiring.tuist generate --no-openbilan loyihani yasang. - Helper yozish.
Tuist/ProjectDescriptionHelpers/Module.swift'ga darsdagiProject.module(name:)helper'ini yozing, ikkita modul (CoreKit,Logger) yarating,Workspace.swiftbilan birlashtiring vatuist generate --no-openbilan yasang. Har bir modul uchun atigi 3 qatorProject.swiftyozilganiga ishonch hosil qiling. - ⭐ Implicit dependency'ni tutish. Bir modulni boshqasida
importqiling, lekinProject.swift'da dependency'ni e'lon qilmang.tuist inspect dependenciesishga tushiring va "implicitly depends on" xatosini oling. So'ng dependency'ni e'lon qilib, tekshiruv "We did not find any dependency issues" berishini tasdiqlang. Exit code'niecho $?bilan tekshiring (xato: 1, toza: 0). - Grafni o'qish.
tuist graph --format dot --no-openishga tushiring vagraph.dot'ni oching. Qaysi target qaysi target'ga strelka chizadi? Test target'lari grafda qanday shaklda ko'rinadi? - ⭐ Hash o'zgarishini kuzatish.
tuist hash cache'ni ishga tushirib hash'ni yozib oling. Bir modulning Swift faylini o'zgartiring va qayta ishga tushiring. Qaysi hash o'zgardi, qaysi biri o'zgarmadi? Bu cache qanday "nima qayta qurilishi"ni hal qilishini ko'rsatadi. - Versiyani pin qilish. Loyihada
mise use tuist@4.211.1bilan versiyani pin qiling (yokimise.toml'ni qo'lda yozing).mise.toml'ni git'ga qo'shing, lekin.xcodeproj/.xcworkspace.gitignore'da ekanini tasdiqlang. Nega biri commit qilinadi, boshqasi yo'q — bir jumlada tushuntiring.
O'zingizni tekshiring {#checklist}
- [ ]
Tuist/papkasi (yokiTuist.swift) loyiha ildizini belgilashini va buyruqlar uni yuqoriga qarab qidirishini tushunaman. - [ ]
.xcodeproj,.xcworkspace,Derived/,Tuist/.build— bularning hammasi.gitignore'da bo'lishi kerakligini bilaman. - [ ] Yangi loyiha oqimini bilaman:
tuist install→tuist generate→ Xcode. - [ ]
tuist buildendi build qilmasligini (faqat yozuvlarni ko'rsatishini) bilaman. - [ ]
tuist inspect dependenciesimplicit va redundant bog'liqliklarni topishini va CI gate sifatida ishlashini bilaman. - [ ]
tuist focus→tuist generate <target>,tuist fetch→tuist installo'zgarishlarini bilaman. - [ ] Tashqi SPM paketlar
Tuist/.build'ga resolve bo'lishini (eskiTuist/Dependenciesemas) bilaman. - [ ] Tuist versiyasini
mise.toml'da pin qilib, uni git'ga commit qilish kerakligini bilaman.
Xulosa {#xulosa}
- Tuist'da papka tuzilmasi — loyihaning o'zi.
.xcodeprojhar safar Swift manifest'lardan generatsiya qilinadi, shuning uchun tuzilmani tushunish birinchi qadam. - **
Tuist/papkasi** ildizni belgilaydi; ichidaPackage.swift(tashqi deps) vaProjectDescriptionHelpers/(shared kod) bo'ladi. Helper factory manifest'larni o'nlab marta qisqartiradi. - Git'da faqat manba: manifest'lar + kod +
.gitignore+mise.toml. Generatsiya fayllari (*.xcodeproj,*.xcworkspace,Derived/,Tuist/.build) —.gitignore'da. Bu merge conflict'larni yo'qotadi. - CLI to'rt toifa: kundalik oqim (
init,install,generate, test), ko'rish (graph,dump), tekshirish (inspect,hash,migration), server (auth,share,registry,account— akkaunt kerak). - **
tuist inspect dependencies** eskienforceExplicitDependencies'ning o'rnini bosdi — bitta buyruq implicit va redundant bog'liqliklarni tutadi va exit code 1 bilan CI'ni to'xtatadi. - O'zgargan buyruqlarni yodda tuting:
focus→generate <target>,fetch→install,build <scheme>→xcodebuild,--external-only→--cache-profile only-external,Config.swift→Tuist.swift. - O'lchangan:
tuist generate~0.55 s (iliq), 1.32 s (cold) — arzon, bemalol ishlating. - Keyingi dars: 04. Dependency'lar — target, project, SPM paketlari, XCFramework, macro'lar, Registry va implicit import tekshiruvi
Manbalar {#manbalar}
- Tuist — Directory structure — tavsiya etilgan papka tuzilmasi,
Tuist/ildizi - Tuist — Editing —
tuist editoqimi va.tuistignore - Tuist — CLI directories —
TUIST_XDG_*env'lar, config/cache/state kataloglari - Tuist — Release channels — canary / RC / stable, versiyani pin qilish
- Tuist — Install Tuist — mise va Homebrew bilan o'rnatish
- Tuist — CLI reference — barcha buyruqlar ro'yxati
- Asana — Scaling a mature iOS codebase with Tuist — ~1 400 qatorli manifest, Tuist vs Bazel tanlovi, 45s → 15s
- Tuist GitHub — releases — versiyalar tarixi (4.211.x)