Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. SemVer tuzilishi
- 2.2. Qachon qaysi raqamni oshirish
- 2.3. Buzuvchi o'zgarish nima
- 2.4. Pre-release versiyalar
- 2.5. 0.x versiyalash
- 2.6. Versiyani kodda saqlash
- 2.7. O'zgarishlar jurnali (CHANGELOG)
- 2.8. SemVer buzilishi
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — SemVer qoidalari
- Misol 2 — Buzuvchi o'zgarishni aniqlash
- Misol 3 — Pre-release va 0.x versiyalash
- Misol 4 — Amaliy: versiya va CHANGELOG boshqaruvi
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
19.5-dars: Semantik versiyalash
19-QISM — PAKETLASH VA CHIQARISH · 5-dars
1. Kirish va motivatsiya
Paketni nashr qildingiz 19.4-bob. Vaqt o'tadi — xato tuzatasiz, yangi imkoniyat qo'shasiz, ba'zan API ni o'zgartirasiz. Har o'zgarish uchun yangi versiya chiqarasiz. Lekin versiya raqamini qanday tanlash kerak? 1.0.0 dan keyin 1.0.1 mi, 1.1.0 mi, yoki 2.0.0 mi? Bu tasodifiy tanlov emas — semantik versiyalash (SemVer) versiya raqamiga ma'no beradi: raqamning o'zi foydalanuvchiga o'zgarish turini aytadi.
To'g'ri versiyalash foydalanuvchilarga ishonch beradi: ular yangilanish xavfsiz (xato tuzatish) yoki ehtiyot talab qiladi (buzuvchi o'zgarish) ekanini versiya raqamidan biladi.
Real vaziyat. Bir kutubxona muallifi funksiya nomini o'zgartirdi va uni patch versiya (1.2.3 → 1.2.4) sifatida chiqardi. Foydalanuvchilar ~=1.2 (patch yangilanishlarga ruxsat, 18.2) ishlatgani uchun avtomatik yangi versiyani oldilar — va ularning kodi buzildi, chunki eski funksiya nomi yo'q edi. Bu SemVer buzilishi edi: API o'zgarishi asosiy (major) versiya bo'lishi kerak edi (2.0.0). Muallif buni tushundi va SemVer qoidalariga qat'iy amal qila boshladi: buzuvchi o'zgarish — major, yangi imkoniyat — minor, xato tuzatish — patch. Foydalanuvchilar ishonchni tikladi.
Bu darsda semantik versiyalashni — versiya raqamiga ma'no berishni o'rganamiz.
Bu darsda:
- SemVer:
ASOSIY.KICHIK.PATCH - Qachon qaysi raqamni oshirish
- Pre-release versiyalar (alpha, beta, rc)
0.xversiyalash- Versiyani kodda saqlash
- O'zgarishlar jurnali (CHANGELOG)
- SemVer buzilishi va oqibatlari
- Amaliy: versiya boshqaruvi
ℹ Misollarda versiya mantig'i uchun
packaging.version18.2-bob ishlatiladi.
2. Nazariya — chuqur tushuntirish
2.1. SemVer tuzilishi
Semantik versiya uch qismdan iborat: ASOSIY.KICHIK.PATCH (masalan 2.5.3):
| Qism | Ingliz | Qachon oshadi |
|---|---|---|
| ASOSIY | MAJOR | Moslikni buzuvchi o'zgarish |
| KICHIK | MINOR | Yangi imkoniyat (mos) |
| PATCH | PATCH | Xato tuzatish (mos) |
2.5.3
│ │ └── PATCH — xato tuzatishlar
│ └──── KICHIK — yangi imkoniyatlar
└────── ASOSIY — buzuvchi o'zgarishlarSemVer shartnomasi: versiya raqami o'zgarish turini aytadi — foydalanuvchi yangilanish xavfini raqamidan biladi.
2.2. Qachon qaysi raqamni oshirish
| O'zgarish | Misol | Versiya |
|---|---|---|
| Xato tuzatish | Noto'g'ri hisob tuzatildi | 1.2.3 → 1.2.4 (PATCH) |
| Yangi imkoniyat | Yangi funksiya qo'shildi | 1.2.3 → 1.3.0 (KICHIK) |
| Buzuvchi o'zgarish | Funksiya olib tashlandi/nomlandi | 1.2.3 → 2.0.0 (ASOSIY) |
Muhim qoida: quyi raqam oshganda, pastdagilar nolga tushadi: 1.2.3 da minor oshsa → 1.3.0 (patch nol), major oshsa → 2.0.0 (minor va patch nol).
2.3. Buzuvchi o'zgarish nima
Buzuvchi (breaking) o'zgarish — mavjud foydalanuvchi kodini buzadigan o'zgarish:
| Buzuvchi (MAJOR) | Buzmaydigan (MINOR/PATCH) |
|---|---|
| Funksiya olib tashlash | Yangi funksiya qo'shish |
| Funksiya nomini o'zgartirish | Yangi ixtiyoriy parametr |
| Parametr olib tashlash | Xato tuzatish |
| Qaytish turini o'zgartirish | Ichki refaktoring |
| Majburiy parametr qo'shish | Hujjat yaxshilash |
Savol: "bu o'zgarish mavjud foydalanuvchi kodini buzadimi?" Ha → MAJOR; yo'q, yangi → MINOR; yo'q, tuzatish → PATCH.
2.4. Pre-release versiyalar
Barqaror versiyadan oldin sinov versiyalari:
1.0.0-alpha.1 # alpha — erta, beqaror
1.0.0-beta.1 # beta — funksiyalar to'liq, sinovda
1.0.0-rc.1 # rc (release candidate) — deyarli tayyor
1.0.0 # barqaror (stable)| Belgi | Ma'nosi |
|---|---|
alpha |
Erta sinov, ko'p o'zgaradi |
beta |
Funksiyalar to'liq, xatolar bor |
rc |
Nomzod — chiqishga tayyor |
Pre-release versiyalar barqaror versiyadan oldin keladi: 1.0.0-rc.1 < 1.0.0. Ular pip install da sukut bo'yicha o'rnatilmaydi (--pre kerak).
2.5. 0.x versiyalash
1.0.0 dan oldingi (0.x.y) versiyalar — barqaror emas:
| Versiya | Ma'nosi |
|---|---|
0.x.y |
Dastlabki rivojlanish — API o'zgarishi mumkin |
0.1.0 → 0.2.0 |
0.x da minor buzuvchi bo'lishi mumkin |
1.0.0 |
Birinchi barqaror API — SemVer to'liq kuchga kiradi |
0.x da SemVer qoidalari yumshoqroq: 0.x da har o'zgarish buzuvchi bo'lishi mumkin. 1.0.0 — "API barqaror" e'loni.
2.6. Versiyani kodda saqlash
Versiyani bir joyda saqlang (takror yo'q):
# src/wisar/__init__.py
__version__ = "1.2.3"# pyproject.toml
dynamic = ["version"]
[tool.hatch.version]
path = "src/wisar/__init__.py" # __version__ dan oladi (19.2) Dinamik versiya bilan versiya __init__.py da bir marta yoziladi; pyproject.toml, wheel nomi va PyPI undan oladi.
2.7. O'zgarishlar jurnali (CHANGELOG)
CHANGELOG.md — har versiyada nima o'zgarganini hujjatlaydi:
# O'zgarishlar
## [1.3.0] - 2026-09-17
### Qo'shildi
- Yangi `export_csv` funksiyasi
## [1.2.4] - 2026-09-10
### Tuzatildi
- `hisobla` da nolga bo'lish xatosiCHANGELOG — foydalanuvchiga yangilanishda nima o'zgarganini aytadi. "Keep a Changelog" formati keng tarqalgan (Qo'shildi/O'zgardi/Tuzatildi/Olib tashlandi).
2.8. SemVer buzilishi
| Buzilish | Oqibat |
|---|---|
| Buzuvchi o'zgarish patch sifatida | Foydalanuvchi kodi buziladi |
| Har o'zgarish major | Foydalanuvchi qo'rqadi (juda tez major) |
| Versiya sakrash (1.0 → 3.0) | Chalkashlik |
| Versiyani kamaytirish | Mumkin emas (o'sib borishi kerak) |
SemVer — shartnoma: uni buzsangiz, foydalanuvchilar ~=/>= ga ishona olmaydi va yangilanishdan qo'rqadi. Qat'iy amal qiling.
3. Tez ma'lumotnoma
ASOSIY.KICHIK.PATCH (masalan 2.5.3)
MAJOR — buzuvchi o'zgarish (2.0.0)
MINOR — yangi imkoniyat (1.3.0)
PATCH — xato tuzatish (1.2.4)
pre-release: 1.0.0-alpha.1 < beta.1 < rc.1 < 1.0.0
0.x.y — barqaror emas; 1.0.0 — barqaror API# versiya bir joyda:
__version__ = "1.2.3" # __init__.py
# pyproject.toml: dynamic = ["version"]Qoidalar
buzuvchi → major; yangi → minor; tuzatish → patch
quyi raqam oshsa, pastdagilar nolga
0.x — barqaror emas; 1.0.0 — API barqaror
pre-release: alpha < beta < rc < stable
versiyani bir joyda (dinamik)
CHANGELOG bilan o'zgarishlarni hujjatlang
SemVer — shartnoma, buzmang4. Batafsil misollar
Misollarda versiya mantig'i uchun
packaging.versionishlatiladi.
Misol 1 — SemVer qoidalari
"""ASOSIY.KICHIK.PATCH; qaysi o'zgarishga qaysi raqam; quyi raqam oshsa pastdagilar nolga; versiya taqqoslash."""
from packaging.version import Version
def keyingi_versiya(joriy: str, ozgarish: str) -> str:
v = Version(joriy)
asosiy, kichik, patch = v.major, v.minor, v.micro
if ozgarish == "major":
return f"{asosiy + 1}.0.0" # pastdagilar nolga
if ozgarish == "minor":
return f"{asosiy}.{kichik + 1}.0" # patch nolga
if ozgarish == "patch":
return f"{asosiy}.{kichik}.{patch + 1}"
raise ValueError(ozgarish)
def main() -> None:
print("=== 1. Versiya tuzilishi ===")
v = Version("2.5.3")
print(f" 2.5.3 → ASOSIY={v.major}, KICHIK={v.minor}, PATCH={v.micro}")
print("\n=== 2. Keyingi versiya (o'zgarish turiga qarab) ===")
joriy = "1.2.3"
for ozgarish, izoh in [("patch", "xato tuzatish"), ("minor", "yangi imkoniyat"), ("major", "buzuvchi o'zgarish")]:
yangi = keyingi_versiya(joriy, ozgarish)
print(f" {joriy} + {ozgarish:6} ({izoh:18}) → {yangi}")
print("\n=== 3. ⭐ Quyi raqam oshsa, pastdagilar nolga ===")
print(f" 1.2.3 minor → {keyingi_versiya('1.2.3', 'minor')} (patch nolga)")
print(f" 1.2.3 major → {keyingi_versiya('1.2.3', 'major')} (minor va patch nolga)")
print("\n=== 4. Versiya taqqoslash ===")
print(f" 2.0.0 > 1.9.9: {Version('2.0.0') > Version('1.9.9')}")
print(f" 1.10.0 > 1.9.0: {Version('1.10.0') > Version('1.9.0')} (10 > 9, satr emas)")
print(f" 1.2.3 == 1.2.3: {Version('1.2.3') == Version('1.2.3')}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Versiya tuzilishi ===
2.5.3 → ASOSIY=2, KICHIK=5, PATCH=3
=== 2. Keyingi versiya (o'zgarish turiga qarab) ===
1.2.3 + patch (xato tuzatish ) → 1.2.4
1.2.3 + minor (yangi imkoniyat ) → 1.3.0
1.2.3 + major (buzuvchi o'zgarish) → 2.0.0
=== 3. ⭐ Quyi raqam oshsa, pastdagilar nolga ===
1.2.3 minor → 1.3.0 (patch nolga)
1.2.3 major → 2.0.0 (minor va patch nolga)
=== 4. Versiya taqqoslash ===
2.0.0 > 1.9.9: True
1.10.0 > 1.9.0: True (10 > 9, satr emas)
1.2.3 == 1.2.3: TrueNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Buzuvchi o'zgarishni aniqlash
"""o'zgarish buzuvchimi (major) yoki qo'shuvchimi (minor) yoki tuzatuvchimi (patch); API o'zgarishlarini toifalash; to'g'ri versiya taklifi."""
from packaging.version import Version
def versiya_turi(ozgarish_turi: str) -> str:
buzuvchi = {"funksiya_olib_tashlash", "nom_ozgartirish", "parametr_olib_tashlash", "qaytish_turi_ozgarish", "majburiy_parametr"}
qoshuvchi = {"yangi_funksiya", "ixtiyoriy_parametr", "yangi_imkoniyat"}
tuzatuvchi = {"xato_tuzatish", "hujjat", "ichki_refaktoring", "tezlik"}
if ozgarish_turi in buzuvchi:
return "major"
if ozgarish_turi in qoshuvchi:
return "minor"
if ozgarish_turi in tuzatuvchi:
return "patch"
return "nomalum"
def main() -> None:
print("=== 1. O'zgarishlarni toifalash ===")
ozgarishlar = [
("xato_tuzatish", "hisobda nolga bo'lish tuzatildi"),
("yangi_funksiya", "export_csv qo'shildi"),
("funksiya_olib_tashlash", "eski salom() olib tashlandi"),
("ixtiyoriy_parametr", "format= ixtiyoriy parametr"),
("nom_ozgartirish", "hisobla → calculate"),
("hujjat", "README yaxshilandi"),
("majburiy_parametr", "yangi majburiy 'kalit' argument"),
]
for tur, izoh in ozgarishlar:
versiya = versiya_turi(tur)
belgi = "🔴" if versiya == "major" else "🟡" if versiya == "minor" else "🟢"
print(f" {belgi} {versiya:6} — {izoh}")
print("\n=== 2. Kalit savol ===")
print(" 'Bu o'zgarish mavjud foydalanuvchi kodini buzadimi?'")
print(" Ha → major | Yo'q, yangi → minor | Yo'q, tuzatish → patch")
print("\n=== 3. Misol: bir nechta o'zgarish ===")
o_lar = ["xato_tuzatish", "yangi_funksiya", "funksiya_olib_tashlash"]
turlar = [versiya_turi(o) for o in o_lar]
# eng yuqori o'zgarish belgilaydi
if "major" in turlar:
yakuniy = "major"
elif "minor" in turlar:
yakuniy = "minor"
else:
yakuniy = "patch"
print(f" o'zgarishlar: {turlar}")
print(f" yakuniy versiya turi: {yakuniy} (eng yuqori o'zgarish belgilaydi)")
print(f" 1.2.3 → {'2.0.0' if yakuniy == 'major' else '1.3.0' if yakuniy == 'minor' else '1.2.4'}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. O'zgarishlarni toifalash ===
🟢 patch — hisobda nolga bo'lish tuzatildi
🟡 minor — export_csv qo'shildi
🔴 major — eski salom() olib tashlandi
🟡 minor — format= ixtiyoriy parametr
🔴 major — hisobla → calculate
🟢 patch — README yaxshilandi
🔴 major — yangi majburiy 'kalit' argument
=== 2. Kalit savol ===
'Bu o'zgarish mavjud foydalanuvchi kodini buzadimi?'
Ha → major | Yo'q, yangi → minor | Yo'q, tuzatish → patch
=== 3. Misol: bir nechta o'zgarish ===
o'zgarishlar: ['patch', 'minor', 'major']
yakuniy versiya turi: major (eng yuqori o'zgarish belgilaydi)
1.2.3 → 2.0.0Nima ko'rsatdi: 2.3-bo'lim.
Misol 3 — Pre-release va 0.x versiyalash
"""pre-release: alpha < beta < rc < stable; tartib; --pre bilan o'rnatiladi; 0.x barqaror emas; 1.0.0 barqaror API."""
from packaging.version import Version
def main() -> None:
print("=== 1. Pre-release tartibi ===")
versiyalar = ["1.0.0a1", "1.0.0b1", "1.0.0rc1", "1.0.0"]
saralangan = sorted(versiyalar, key=Version)
print(f" saralangan: {saralangan}")
print(f" 1.0.0-alpha < 1.0.0-beta: {Version('1.0.0a1') < Version('1.0.0b1')}")
print(f" 1.0.0-rc < 1.0.0 (barqaror): {Version('1.0.0rc1') < Version('1.0.0')}")
print("\n=== 2. Pre-release turlari ===")
turlar = [
("alpha (a)", "erta sinov, ko'p o'zgaradi"),
("beta (b)", "funksiyalar to'liq, xatolar bor"),
("rc (release candidate)", "chiqishga tayyor nomzod"),
("stable", "barqaror, tavsiya etiladi"),
]
for tur, izoh in turlar:
print(f" {tur:24} — {izoh}")
print("\n=== 3. Pre-release aniqlash ===")
for v_str in ["1.0.0a1", "1.0.0", "2.1.0rc2"]:
v = Version(v_str)
print(f" {v_str}: pre-release={v.is_prerelease}")
print(" ⭐ pre-release pip da sukut o'rnatilmaydi (--pre kerak)")
print("\n=== 4. 0.x vs 1.0.0 ===")
print(f" 0.5.0: barqaror emas (API o'zgarishi mumkin)")
print(f" 1.0.0: birinchi barqaror API (SemVer to'liq kuchga kiradi)")
print(f" 0.5.0 < 1.0.0: {Version('0.5.0') < Version('1.0.0')}")
print(" ⚠️ 0.x da har o'zgarish buzuvchi bo'lishi mumkin")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Pre-release tartibi ===
saralangan: ['1.0.0a1', '1.0.0b1', '1.0.0rc1', '1.0.0']
1.0.0-alpha < 1.0.0-beta: True
1.0.0-rc < 1.0.0 (barqaror): True
=== 2. Pre-release turlari ===
alpha (a) — erta sinov, ko'p o'zgaradi
beta (b) — funksiyalar to'liq, xatolar bor
rc (release candidate) — chiqishga tayyor nomzod
stable — barqaror, tavsiya etiladi
=== 3. Pre-release aniqlash ===
1.0.0a1: pre-release=True
1.0.0: pre-release=False
2.1.0rc2: pre-release=True
⭐ pre-release pip da sukut o'rnatilmaydi (--pre kerak)
=== 4. 0.x vs 1.0.0 ===
0.5.0: barqaror emas (API o'zgarishi mumkin)
1.0.0: birinchi barqaror API (SemVer to'liq kuchga kiradi)
0.5.0 < 1.0.0: True
⚠️ 0.x da har o'zgarish buzuvchi bo'lishi mumkinNima ko'rsatdi: 2.4, 2.5-bo'limlar.
Misol 4 — Amaliy: versiya va CHANGELOG boshqaruvi
Loyihaning versiya boshqaruvini avtomatlashtiruvchi yordamchi yozamiz: o'zgarishlar ro'yxatiga qarab keyingi versiyani hisoblaydi, __init__.py dagi versiyani yangilaydi va CHANGELOG yozuvi yaratadi. Bu — har chiqishda bajarilodigan versiya boshqaruvi ish oqimi.
"""versiya boshqaruvi: o'zgarishlardan versiya turini aniqlash, keyingi versiyani hisoblash, __init__.py yangilash, CHANGELOG yozuvi; to'liq oqim."""
import re
from packaging.version import Version
def versiya_turi(o_lar: list[str]) -> str:
if any(o["tur"] == "buzuvchi" for o in o_lar):
return "major"
if any(o["tur"] == "qoshildi" for o in o_lar):
return "minor"
return "patch"
def keyingi(joriy: str, tur: str) -> str:
v = Version(joriy)
if tur == "major":
return f"{v.major + 1}.0.0"
if tur == "minor":
return f"{v.major}.{v.minor + 1}.0"
return f"{v.major}.{v.minor}.{v.micro + 1}"
def changelog_yoz(versiya: str, sana: str, o_lar: list[str]) -> str:
guruhlar = {"qoshildi": "Qo'shildi", "buzuvchi": "O'zgardi (buzuvchi)", "tuzatildi": "Tuzatildi"}
satrlar = [f"## [{versiya}] - {sana}"]
for kalit, sarlavha in guruhlar.items():
tegishli = [o["matn"] for o in o_lar if o["tur"] == kalit]
if tegishli:
satrlar.append(f"### {sarlavha}")
satrlar.extend(f"- {m}" for m in tegishli)
return "\n".join(satrlar)
def main() -> None:
joriy = "1.2.3"
ozgarishlar = [
{"tur": "tuzatildi", "matn": "hisobla() da nolga bo'lish xatosi"},
{"tur": "qoshildi", "matn": "export_csv() funksiyasi"},
]
print("=== 1. O'zgarishlar ===")
for o in ozgarishlar:
print(f" [{o['tur']}] {o['matn']}")
print("\n=== 2. Keyingi versiya ===")
tur = versiya_turi(ozgarishlar)
yangi = keyingi(joriy, tur)
print(f" joriy: {joriy}")
print(f" o'zgarish turi: {tur} (yangi imkoniyat bor → minor)")
print(f" keyingi versiya: {yangi}")
print("\n=== 3. __init__.py yangilash ===")
init_matn = f'__version__ = "{joriy}"\n'
yangi_matn = re.sub(r'__version__ = "[^"]+"', f'__version__ = "{yangi}"', init_matn)
print(f" oldin: {init_matn.strip()}")
print(f" keyin: {yangi_matn.strip()}")
print("\n=== 4. CHANGELOG yozuvi ===")
changelog = changelog_yoz(yangi, "2026-09-17", ozgarishlar)
for qator in changelog.splitlines():
print(f" {qator}")
print(" ⭐ versiya + CHANGELOG — har chiqishda birga yangilanadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. O'zgarishlar ===
[tuzatildi] hisobla() da nolga bo'lish xatosi
[qoshildi] export_csv() funksiyasi
=== 2. Keyingi versiya ===
joriy: 1.2.3
o'zgarish turi: minor (yangi imkoniyat bor → minor)
keyingi versiya: 1.3.0
=== 3. __init__.py yangilash ===
oldin: __version__ = "1.2.3"
keyin: __version__ = "1.3.0"
=== 4. CHANGELOG yozuvi ===
## [1.3.0] - 2026-09-17
### Qo'shildi
- export_csv() funksiyasi
### Tuzatildi
- hisobla() da nolga bo'lish xatosi
⭐ versiya + CHANGELOG — har chiqishda birga yangilanadiNima ko'rsatdi: 2.2, 2.6, 2.7-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Versiya raqami tasodifiy" | SemVer — raqamga ma'no beradi |
| "Har o'zgarish major" | Faqat buzuvchi o'zgarish major |
| "Xato tuzatish minor" | Patch |
| "1.9.0 dan keyin 2.0.0" | 1.10.0 (raqam, satr emas) |
| "0.x barqaror" | Barqaror emas — API o'zgaradi |
| "Versiya ikki joyda" | Bir joyda (dinamik) |
| "CHANGELOG keraksiz" | Foydalanuvchiga o'zgarishlarni aytadi |
| "SemVer ixtiyoriy" | Shartnoma — buzsangiz ishonch yo'qoladi |
6. Keng tarqalgan xatolar va yechimlari
1. Buzuvchi o'zgarishni patch qilish
funksiya nomini o'zgartirib 1.2.4 # ❌ foydalanuvchi kodi buziladi
funksiya nomini o'zgartirib 2.0.0 # ✅ major2. Yangi funksiyani major qilish
yangi funksiya qo'shib 2.0.0 # ❌ foydalanuvchi qo'rqadi
yangi funksiya qo'shib 1.3.0 # ✅ minor3. Pastdagilarni nolga tushirmaslik
1.2.3 → 1.3.3 (minor) # ❌ patch nolga tushmadi
1.2.3 → 1.3.0 # ✅4. Versiyani ikki joyda saqlash
__version__ = "1.2.3" # va pyproject da ham # ❌ takror
dynamic = ["version"] # ✅ bir joyda5. 0.x da SemVer kutish
0.2.0 barqaror API deb ishlatish # ⚠️ 0.x o'zgaradi
# ✅ 1.0.0 ga chiqqach barqaror6. CHANGELOG yo'q
versiya chiqarib, nima o'zgarganini yozmaslik # ❌
# ✅ CHANGELOG.md yangilang7. Versiyani kamaytirish
1.2.0 dan keyin 1.1.0 # ❌ mumkin emas
# ✅ versiya doim o'sib borishi kerak7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 18.2-dars (o'tilgan): versiya belgilagichlari —
~=,>=SemVer'ga tayanadi - 19.2-dars (o'tilgan): pyproject — dinamik versiya
- 19.4-dars (o'tilgan): PyPI — versiyani o'chirib bo'lmaydi
- 28-qism: CI/CD — avtomatik versiyalash va nashr
- 31-qism: karyera — versiyalash professional amaliyot
8. Eng yaxshi amaliyotlar
SemVer'ga qat'iy amal qiling: buzuvchi→major, yangi→minor, tuzatish→patch.
"Foydalanuvchi kodini buzadimi?" savolini bering.
Quyi raqam oshganda pastdagilarni nolga tushiring.
0.x— barqaror emas;1.0.0— barqaror API e'loni.Versiyani bir joyda (dinamik) saqlang.
Har versiyada
CHANGELOG.mdni yangilang.Pre-release (alpha/beta/rc) bilan sinov versiyalarini belgilang.
Versiyani hech qachon kamaytirmang.
9. Amaliy topshiriq
Vazifa 1: Versiyani aniqlang
1.4.2 dan keyin qaysi versiya:
1. xato tuzatildi
2. yangi funksiya qo'shildi
3. funksiya nomi o'zgartirildi
4. ixtiyoriy parametr qo'shildi
5. README yaxshilandi
6. parametr olib tashlandi
7. ichki refaktoring (API o'zgarmadi)
8. yangi funksiya + xato tuzatish (birga)Javoblar
1.4.3(patch)1.5.0(minor)2.0.0(major — buzuvchi)1.5.0(minor)1.4.3(patch)2.0.0(major — buzuvchi)1.4.3(patch)1.5.0(minor — eng yuqori belgilaydi)
Vazifa 2: Xatolarni tuzating
1. # funksiya olib tashlandi
1.2.3 → 1.2.4
2. # yangi funksiya qo'shildi
1.2.3 → 2.0.0
3. # minor oshirish
1.2.3 → 1.3.3
4. # versiya kamaytirish
1.5.0 → 1.4.0
5. # 0.x ni barqaror deb ishlatish
"0.3.0 API barqaror"Javoblar
1. 1.2.3 → 2.0.0 # buzuvchi — major
2. 1.2.3 → 1.3.0 # yangi — minor
3. 1.2.3 → 1.3.0 # patch nolga
4. # versiya kamaymaydi — 1.6.0 (yangi o'zgarish)
5. # 0.x barqaror emas — 1.0.0 ga chiqingVazifa 3: Versiya kalkulyator
keyingi_versiya(joriy, o'zgarishlar):
- O'zgarishlar ro'yxatidan turni aniqlang
- Eng yuqori o'zgarish versiyani belgilasin
- Pre-release variantini ham qo'llang
packaging.versionbilan tekshiring
Vazifa 4: CHANGELOG generatori
Git commitlaridan CHANGELOG:
- Commit xabarlarini toifalang (feat/fix/breaking)
- Versiya turini aniqlang
- "Keep a Changelog" formatida yozing
- Keyingi versiyani taklif qiling
Vazifa 5: SemVer validatori
- Ikki versiya orasidagi o'zgarishni tekshiring
- API o'zgarishiga mos versiya sakraganini tasdiqlang
- SemVer buzilishlarini toping
- Tavsiya bering
Vazifa 6: Versiya tarixi
- Paket versiya tarixini tahlil qiling
- Har o'zgarish turini aniqlang (major/minor/patch nisbati)
- Pre-release versiyalarni toping
- Versiyalash sifatini baholang
Vazifa 7: O'ylash
SemVer keng qabul qilingan standart, lekin tanqidchilar uni "amaliyotda buziladi" deydilar — ko'p loyiha SemVer'ga qat'iy amal qilmaydi, va "buzuvchi o'zgarish" tushunchasi ba'zan noaniq. Nima uchun SemVer ideal bo'lsa ham amalda qiyin, va versiyalash "texnik qaror" dan ko'ra "ijtimoiy shartnoma" ekanini qanday ko'rsatadi?
Javob
Qisqa javob: SemVer amalda qiyin, chunki "buzuvchi o'zgarish" ni aniqlash subyektiv: bir foydalanuvchi uchun buzuvchi bo'lgan o'zgarish (masalan xato tuzatish natijani o'zgartiradi) boshqasi uchun oddiy tuzatish. SemVer — texnik qoida emas, ijtimoiy shartnoma: muallif va foydalanuvchilar o'rtasidagi va'da. Uning kuchi qat'iy raqamlarda emas, balki jamoa ishonchida — versiya raqami va'dani bildiradi, va va'dani bajarish odamga bog'liq.
1. Nega SemVer qiyin
| Qiyinchilik | Tafsilot |
|---|---|
| "Buzuvchi" subyektiv | Kimga buzuvchi? |
| Xato tuzatish natijani o'zgartiradi | Tuzatish yoki buzuvchi? |
| Ichki vs ommaviy API | Chegara noaniq |
| Xatti-harakat o'zgarishi | Imzo emas, xulq |
| Inson qarori | Avtomatlashtirilmaydi |
2. "Buzuvchi" ning noaniqligi
Misollar:
- Xato tuzatish natijani o'zgartiradi (kimdir noto'g'ri natijaga tayangan bo'lsa — buzuvchi)
- Tezlik yaxshilanishi xulqni o'zgartiradi
- Yangi ogohlantirish (warning) — buzuvchimi?
3. Ijtimoiy shartnoma sifatida
| Texnik qaror | Ijtimoiy shartnoma |
|---|---|
| Qat'iy qoida | Va'da |
| Avtomatik | Inson mulohazasi |
| Bir xil talqin | Kontekstga bog'liq |
| Mashina bajaradi | Jamoa ishonchi |
4. Nega baribir foydali
SemVer mukammal bo'lmasa ham, u umumiy til beradi: versiya raqami taxminan nimani anglatishini hamma biladi. Bu ishonch va bashoratlilikni oshiradi — mukammal bo'lmasa ham, hech narsadan yaxshi.
5. Amaliy yondashuv
- SemVer'ga imkon qadar amal qiling
- Shubhali holatda ehtiyotkorlik (major)
- CHANGELOG bilan o'zgarishlarni aniq tushuntiring
- Foydalanuvchi nuqtai nazaridan o'ylang
6. Muhandislik saboqlari
- Ba'zi standartlar ijtimoiy, texnik emas
- Versiyalash — muallif va foydalanuvchi o'rtasidagi va'da
- Mukammal bo'lmagan standart ham qiymatli
- Aniq muloqot (CHANGELOG) qoidadan muhimroq
7. Xulosa
- SemVer qiyin — "buzuvchi" subyektiv
- U texnik qoida emas, ijtimoiy shartnoma
- Kuchi jamoa ishonchida
- Mukammal emas, lekin umumiy til beradi
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda semantik versiyalashni — versiya raqamiga ma'no berishni o'rgandik.
Eng muhim uch fikr:
SemVer:
ASOSIY.KICHIK.PATCHraqamga ma'no beradi. MAJOR — moslikni buzuvchi o'zgarish (2.0.0), MINOR — yangi imkoniyat, mos (1.3.0), PATCH — xato tuzatish, mos (1.2.4). Kalit savol: "bu o'zgarish mavjud foydalanuvchi kodini buzadimi?" — ha bo'lsa major, yangi bo'lsa minor, tuzatish bo'lsa patch. Quyi raqam oshganda pastdagilar nolga tushadi (1.2.3→ minor →1.3.0).Pre-release va
0.x. Barqaror versiyadan oldin sinov versiyalari:1.0.0-alpha.1 < beta.1 < rc.1 < 1.0.0(pip da sukut o'rnatilmaydi,--prekerak).0.x.yversiyalar barqaror emas — API o'zgarishi mumkin;1.0.0"API barqaror" e'loni bo'lib, SemVer to'liq kuchga kiradi. Versiyani bir joyda (__init__.py, dinamik) saqlang va har versiyadaCHANGELOG.mdni yangilang.SemVer — shartnoma, ijtimoiy va'da. Uni buzsangiz (masalan buzuvchi o'zgarishni patch sifatida chiqarsangiz), foydalanuvchilar
~=/>=belgilagichlariga ishona olmaydi va yangilanishdan qo'rqadi. "Buzuvchi o'zgarish" ni aniqlash ba'zan subyektiv — shuning uchun SemVer texnik qoidadan ko'ra muallif va foydalanuvchilar o'rtasidagi ishonchga asoslanadi. Qat'iy amal qiling va CHANGELOG bilan o'zgarishlarni aniq tushuntiring.
Keyingi darsda foydalanuvchilar terminaldan ishlatadigan CLI dastur yaratishni o'rganamiz: argparse va click bilan buyruq qatori interfeysi, argumentlar, bayroqlar va yordamni loyihalash.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!