Abych si přiblížil vývoj na lokálním počítači tomu
ostrému, zprovoznil jsem si lokální https. Jak na to?
Nejsnazší cesta
V komentářích padla zmínka o aplikaci mkcert, která následující
postup udělá za vás. Ale pokud máte rádi ruční práci, čtěte
dál :)
Vygenerujeme SSL certifikát
K tomu použijeme program openssl, který určitě na
počítači najdete, třeba jako součást Gitu na
C:\Program Files\Git\usr\bin\openssl.exe nebo jinde. Následující
příkaz vygeneruje klíč do souboru rootCA.key. Bude to po vás
chtít vymyslet nějaké heslo, které si uložte.
openssl genrsa -des3 -out rootCA.key 2048
Další příkaz z klíče vygeneruje kořenový SSL certifikát a uloží
ho do souboru rootCA.pem. Jeho platnost bude 2000 dní (tedy pět
let), ale číslo klidně změňte:
Teď oznámíme operačnímu systému, aby certifikát považoval za
důvěryhodný. Postup pro Mac jsem našel třeba
tady, pro Windows je pěkně obrázek za obrázkem sepsaný
zde a pro české Windows jsem vám jej přeložil:
spustit mmc
v menu Soubor > Přidat nebo odebrat moduly snap-in
doubleclick na Certifikáty v levém okně
zvolte Účet počítače a Další
ponechte Místní počítač a Dokončit
zavřete okno tlačítkem OK
v levém okně zvolte Certifikáty, v pravém Důvěryhodné kořenové
certifikační autority
pravé tlačítko a v kontextovém menu Všechny úkoly >
Importovat
objeví se Průvodce importem certifikátu, dejte Další
vyberte soubor rootCA.pem a odklikejte průvodce na konec
Ufff, jsme v půlce. Pokračujeme v Konzoli:
opět v menu Soubor > Přidat nebo odebrat moduly snap-in
doubleclick na Editor objektů zásad skupiny
stiskněte Dokončit a zavřete okno tlačítkem OK
v levém okně otevřete Místní počítač – zásady > Konfigurace
počítače > Nastavení systému Windows > Nastavení zabezpečení >
Zásady veřejných klíčů
doubleclick na Nastavení ověření cesty certifikátů
zatrhněte Definovat tato nastavení, Povolit ověřování certifikátů
… a Povolit uživatelům důvěřovat certifikátum …
potvrďte tlačítkem OK
Hotovo, zavřete Konzoli.
Všichni už certifikátu věří, akorát Firefox chce ještě
popostrčit:
Klikačku máme za sebou, teď vyrobíme certifikáty pro server. Vytvoříme
soubor server.csr.cnf s tímto obsahem:
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C = CZ
ST = Random
L = Random
O = Random
OU = Random
emailAddress = example@example.com
CN = localhost
A dále soubor v3.ext, kde bude uveden seznam všech domén,
které na localhostu provozujete:
Jak vidíte, lokální verze webů provozuji na doménách, které končí na
.l, u vás to třeba bude jinak. Ty jednotlivé klíče
DNS.1 apod. je potřeba fakt jako idiot postupně očíslovat.
Následujícím krokem vygenerujeme soubory server.key a
server.csr:
Všechny dosud vytvořené soubory včetně hesla si někam uložte. Ať se
totiž změní domény, které provozujete lokálně, jen upravíte
v3.ext a posledním příkazem znovu vygenerujete certifikát pro
server.
Konfigurace webového serveru
Zbývá povolit https na serveru. Tj. nakonfigurovat server tak, aby
naslouchal na portu 443, na kterém běží https, a používal vygenerovaný
certifikát.
Používám Apache, do jehož konfiguračního soubor httpd.conf
jsem přidal následující řádky s cestou k souborům
server.key a server.crt:
Content Security Policy (CSP) je dodatečný bezpečnostní prvek, který
prohlížeči říká, jaké další zdroje může stránka načítat a jak
může být zobrazena. Chrání tak před vkládáním škodlivého kódu a
útokům jako je XSS. Odesílá se v podobě hlavičky sestavené z řady direktiv.
Jeho nasazení ale není vůbec triviální.
Obvykle chceme používat JavaScriptové knihovny umístěné na různých
místech mimo náš server, například měřící kód Google Analytics,
reklamní systémy, captchy atd. A tady bohužel první verze CSP selhává.
Vyžaduje přesnou analýzu načítaného obsahu a nastavení správných
pravidel. Tedy vytvořit whitelist, výčet všech domén, což není snadné,
jelikož některé skripty dynamicky dotahují další skripty z jiných
domén, nebo jsou na jiné domény přesměrované atd. A i když si dáte
práci a seznam vytvoříte ručně, nikdy nevíte, co se může v budoucnu
změnit, takže musíte neustále sledovat, jestli je seznam stále aktuální a
opravovat ho. Analýza Google ukázala, že i to pečlivé ladění ve finále
vede k tomu, že povolíte tak široký přístup, že celý smysl CSP padá,
jen posíláte s každým požadavek mnohem větší hlavičky.
CSP level 2 už k problému přistupuje jinak, pomocí nonce, nicméně
teprve třetí verze řešení dotáhla do konce. Bohužel zatím (rok 2019)
nemá dostatečnou podporu u prohlížečů.
O tom, jak sestavit direktivy script-src a
style-src, aby správně fungovaly i ve starších
prohlížečích a přitom s tím bylo co nejméně práce, jsem sepsal podrobný
článek v partnerské sekci Nette. V zásadě výsledná podoba může
vypadat nějak takto:
Než nastavíte nová pravidla pro CSP, vyzkoušejte si je nejprve nanečisto
pomocí hlavičky Content-Security-Policy-Report-Only. Ta funguje
ve všech prohlížečích podporujících CSP. Při porušení pravidel
prohlížeč nezablokuje skript, ale jen pošle notifikaci na URL uvedené
v direktivě report-uri. K příjmu notifikací a jejich analýze
můžete použít třeba službu Report
URI.
Můžete zároveň používat obě hlavičky a v
Content-Security-Policy mít ověřené a aktivní pravidla a
zároveň v Content-Security-Policy-Report-Only si testovat jejich
úpravu. Samozřejmě i selhání ostrých pravidlech si můžete nechat
monitorovat.
Názvoslovný oříšek: jak souhrnně označovat třídy a rozhraní? Jak
třeba nazvat proměnnou, která může obsahovat jak název třídy, tak
rozhraní? Co zvolit místo $class?
Dá se tomu říkat type ($type), nicméně to je zase
příliš obecné, protože typem je i řetězec nebo pole. Z pohledu jazyka
jím může být i něco komplikovanějšího, třeba ?array.
Navíc je sporné, co je v případě objektu jeho typ: je jím název třídy,
nebo je to object?
Nicméně souhrnné označení pro třídy a rozhraní skutečně existuje:
je jím slovo třída.
Cože?
Z pohledu deklarace je interface hodně ořezaná třída. Může obsahovat
jen veřejné abstraktní metody. Což také implikuje nemožnost vytvářet
objekty. Rozhraní jsou tedy podmnožinou tříd. A pokud je něco
podmnožinou, tak to můžeme označovat názvem nadmnožiny. Člověk je savec,
stejně jako rozhraní je třída.
Nicméně je tady ještě pohled užití. Třída může dědit jen od
jedné třídy, ale může implementovat vícero rozhraní. Nicméně tohle je
omezení týkající se tříd, samotné rozhraní za to nemůže. Obdobně:
třída nemůže dědit od final třídy, ale přitom final třídu pořád
vnímáme jako třídu. A také pokud třída může implementovat víc
rozhraní (tj. tříd, viz 1.), stále je vnímejme jako třídy.
A co traity? Ty sem vůbec nepatří, z hlediska OOP jednoduše
neexistují.
Tedy problém se společným pojmenováním tříd a rozhraní je vyřešen.
Říkejme jim prostě třídy.
classes + interfaces = classes
No jo, ale vznikl tady problém nový. Jak říkat třídám, které nejsou
rozhraní? Tedy jejich doplňku. Tomu, co se ještě na začátku článku
nazývalo třídy. Nerozhraní? Nebo implementations? 🙂
To je ještě větší oříšek. To je pořádný ořech. Víte co, raději
zapomeňme na to, že rozhraní jsou také třídy, a tvařme se opět, že
každý OOP identifikátor je buď třída, nebo rozhraní. Bude to
snazší.
Stylish
je doplněk do Chrome, který umožňuje přidat webovým stránkám vlastní
CSS styly.
(Lze ho nainstalovat i do nové Opery, nejprve si přidejte Download
Chrome extension a pak už ho přímo nainstalujete z Chrome webstore.)
Stylish jsem si přidal kvůli GitHubu, který mě štve příliš širokými
tabulátory a hlavně nezalamováním řádků s textem, bez čehož se podobné commity
vůbec nedají číst.
Naučit se psát všemi deseti, zvládnou správné
prstoklady – to je nepochybně prima přednost. Ale mezi námi, sám datluji
celý život dvěma prsty a při psaní přikládám daleko větší důraz
něčemu jinému. A tím je rozložení klávesnice.
Řešením je si vytvořit vlastní rozložení klávesnice. To své jsem si
vypiplal asi před
deseti lety a je vhodné pro programátory, webdesignery, copywritery,
obsahuje všechny důležité typografické vychytávky, jako je pomlčka, dvojité a
jednoduché uvozovky atd., intuitivně umístěné. Rozložení si můžete
samozřejmě upravit, viz dále.
Všechny typografické znaky jsou dosažitelné přes pravý Alt, nebo-li
AltGr. Rozložení je intuitivní:
české dvojité uvozovky „“ AltGr-<AltGr->
české jednoduché uvozovky ‚‘ AltGr-Shift-<AltGr-Shift->
Je to snadné a je to zábavné. Přímo od Microsoftu si stáhněte
kouzelný a dobře utajený program Microsoft Keyboard
Layout Creator (ke svému chodu vyžaduje .NET Framework).
Hned při spuštění se Vám zobrazí „prázdná“ klávesnice, tedy
taková, kde ještě není definováno žádné rozložení kláves. Začínat
na zelené louce není to pravé ořechové, proto si najděte v menu příkaz
Load existing keyboard a načtěte některé standardní
rozložení (například klasickou českou klávesnici).
U každé klávesy můžete definovat znak, který se napíše při
samostatném stisku a dále při použití přepínačů (tedy Shift,
Ctrl+Alt (pravý Alt), pravý Alt +Shift,
Caps Lock a Shift+Caps Lock). Dále lze klávesu označit
jako mrtvou (dead key), což znamená, že znak se napíše až po stisknutí
další klávesy. Takto funguje například háček a čárka v české
klávesnici.
Skutečná bomba je export hotové klávesnice. Výsledkem je plnohodnotný
ovladač klávesnice včetně instalačního programu. Takže svou klávesnici
si můžete pověsit na internet a nainstalovat na jiné počítače.
Tuhle jsem zveřejnil skript na cherry-pickování přímo
z GitHubu, který dodnes používám, ale bylo otravné tím stahovat celé
pull requesty, pokud obsahovaly víc komitů. Takže jsem ho naučil stahovat je
na jeden zátah. Opět stačí jako argument uvést URL:
Pull request se stáhne do nové větve s názvem jako
pull-123.
Mám i skript na vytvoření nového pull requestu. Spustíte jej ve větvi,
ze které chcete PR vytvořit, bez parametrů. On větev pushne do vašeho forku
a poté otevře prohlížeč s formulářem pro vytvoření pull requestu:
<?php
$remote = 'dg'; // tady dejte název 'remote' vedoucí k forku na GitHubu
exec('git remote -v', $remotes);
$repo = null;
foreach ($remotes as $rem) {
if (preg_match('#^' . preg_quote($remote) . '\tgit@github.com:(.+)\.git \(#', $rem, $m)) {
$repo = $m[1];
break;
}
}
if (!$repo) {
die('Not Github repo');
}
exec('git rev-parse --abbrev-ref HEAD', $branch);
$branch = $branch[0];
if (!$branch) {
die('Unable to retrieve branch name');
}
echo "Pushing to $repo & $branch\n";
exec("git push --set-upstream $remote $branch");
$url = "https://github.com/$repo/compare/$branch?expand=1";
exec('start "" ' . $url); // tohle otevře prohlížeč pod Windows. Pro jiné OS si upravte.
Už jsem odpověděl na spoustu pull requestů „Can you add
tests?“ Ale ne proto, že bych byl testofil, nebo abych dotyčného
buze prudil.
Pokud posíláte pull request, který opravuje nějakou chybu, tak
pochopitelně musíte před odesláním vyzkoušet, jestli skutečně funguje.
Kolikrát si člověk myslí, že něco snadno fixne a ejhle, rozbije to ještě
víc. Nechci se opakovat, ale tím, že to vyzkoušíte, jste vyrobili test, tak ho jen
přiložte.
(Bohužel někteří lidé svůj kód doopravdy nevyzkouší. Kdyby to šlo,
dával bych měsíční bany za pull requesty vytvořené přímo ve webovém
editoru Githubu.)
Ale to stále není ten nejhlavnější důvod: Test je jediná záruka,
že vaše oprava bude fungovat v budoucnu.
Už mnohokrát se stalo, že někdo poslal pull request, který mi nebyl
užitečný, ale upravoval funkcionalitu důležitou pro něj. Zejména pokud to
byl někdo, koho znám, a vím, že je dobrý programátor, tak jsem to mergnul.
Pochopil jsem, k čemu to chce, nevadilo to ničemu jinému, tak jsem PR
přijal a v tu chvíli vypustil z hlavy.
Pokud svůj pull request doplnil testem, tak jeho kód dodnes funguje a bude
fungovat i nadále.
Pokud ho testem nedoplnil, tak se klidně může stát, že mu to nějaká
další úprava rozbije. Ne schválně, prostě se to stane. Nebo už se to
stalo. A nemá smysl láteřit, jaký jsem vůl, že jsem mu už potřetí
rozbil jeho kód, ačkoliv jsem před 3 lety přijal jeho pull request, si to
snad musím pamatovat né, takže mu to snad dělám naschvál… Nedělám.
Nikdo si nepamatujeme, co jsme měli před třemi lety na svačinu.
Pokud vám na nějaké funkcionalitě záleží, přiložte k ní test.
Pokud vám na ni nezáleží, vůbec ji neposílejte.
Vždycky jsem obdivoval Microsoft, jak dokáže perfektně pojmenovávat
systémové adresáře, třeba takové c:\Documents and Settings namísto
trapného /home nebo /Users, nicméně vždycky mě trápila složka Program
Files, protože na jedné straně je skvělé, že v názvu uvádí, že
uvnitř jsou soubory (což třeba mekaře u takové /Applications vůbec
nemusí napadnout), na druhou stranu úplně opomíjí adresáře.
Navrhuji proto každou složku, která může obsahovat soubory nebo
adresáře, tedy každou složku, doplnit v názvu touto informací. Tedy
v příštích Windows přejmenovat c:\Program Files na přesnější
c:\Program Files and Directories.
To by mohlo zase více posunout Microsoft tam, kde v poslední
době je.
Václav Novotný připravil infografiku porovnávající
aktivitu vývojářů v Nette a Symfony. Rád a zvědavě se podívám, leč
bez vysvětlení metriky umí být čísla krutě zrádná. S nadsázkou: při
určitém workflow a naivním měření mohu ve statistikách vyjít jako autor
100 % kódu, aniž bych naprogramoval jedinou řádku.
I při přímočarých workflow je poměřování množství komitů
zákeřné. Není komit jako komit. Pokud přidáte pětici důležitých
komitů a zároveň deset lidí vám opraví překlepy v komentářích, jste
co do počtu komitů autorem třetiny kódu. Což ale není pravda, jste autorem
celého kódu, opravy překlepů se za autorství (jak ho obvykle vnímáme)
nepovažují.
V GITu dále věc komplikují „merge-commits“. Pokud někdo připraví
zajímavý komit a vy ho schválíte (tedy vznikne ještě merge-commit), jste
autorem poloviny komitů. Ale jaký je vlastně skutečný podíl? Obvykle
nulový, schválení je otázka jednoho kliknutí v GitHubu, byť někdy
diskusí strávíte víc času, než kdybyste si kód napsal sám, ale
neuděláte to, protože potřebujete vývojáře vychovávat.
Proto místo počtu komitů je vhodnější analyzovat jejich obsah.
Nejjednodušší je brát v úvahu počet změněných řádek. Ale i to
může být zavádějící: pokud vytvoříte 100 řádkovou třídu a někdo
jiný soubor s ní jen přejmenuje (či rozdělí na dva), „změnil“
vlastně 200 řádků a opět jste autorem třetiny.
Pokud týden ladíte u sebe několik komitů a až potom je pošlete do
repozitáře, jste v počtu změněných řádek v nevýhodě oproti tomu, kdo
je pošle hned a teprve poté dolaďuje následujícími komity. Nebylo by tedy
od věci analyzovat třeba až souhrny za celý den. Je třeba odfiltrovat
i údržbové komity, zejména ty, které mění u všech souborů letopočet
nebo verzi v hlavičce.
Do toho přicházejí ještě situace, kdy se automatizovaně kopírují
komity z jedné větve do jiné, nebo do jiného repozitáře. Což de facto
znemožňuje dělat jakékoliv globální statistiky.
Analýza jednoho projektu je věda, natož ta srovnávací. Docela mi to
připomíná skvělý analytický kvíz od Honzy
Tichého.