3 usprawnienia organizacji kodu
W pracy programisty często występują zakłócenia w postaci zmian kontekstu. Przerywamy pracę w połowie ze względu na spotkania, ważniejsze zadania albo ujawnioną potrzebę rozwiązania blokujących zadań. W odpowiedzi na te problemy, Android Studio zostało wyposażone w kilka użytecznych funkcjonalności, które opisuję w tym artykule.
Jeśli twoje commity mają opis “WIP”, w pull requestach znajdujesz czasem kod, który nie powinien się tam znaleźć albo po prostu jesteś zainteresowana lub zainteresowany polepszeniem organizacji swojego kodu, zapraszam do lektury.
Spis treści
1. Lista zmian
Lista zmian (ang. changelist) to nic innego jak grupa zmian w kodzie.
Przypuśćmy, że chcemy tymczasowo ustawić wartość pewnej stałej
val initialScreen = Screens.THANK_YOU
Możliwe, że jest to zmiana, której nie będziemy chcieli zakomitować.
W celu odróżnienia tej zmiany od innych, możemy stworzyć nową listę zmian (changelist).
Domyślnie Android Studio ma jedną listę zmian, która się nazywa “Default Changelist”.
Nową listę możemy stworzyć z poziomu menu kontekstowego.
Jak widać znajdują się tam również opcje edycji i usunięcia takiej listy.
Przy próbie stworzenia changelisty pojawi nam się okno dialogowe.
W polu Name nadajemy jej nazwę – sugeruję podejście podobne jak do pierwszej linii commit msga. Legenda:
- Comment – opcjonalny komentarz.
- Set active – ustawia listę zmian jako aktywną. Od tej pory każdy kod, który napiszemy będzie dodany do tej listy zmian.
- Track context – przy zmianie changelisty na inną Android Studio zapamięta otwarte zakładki. Po powrocie do tej zakładki z plikami zostaną przywrócone.
Po stworzeniu changelisty, nasze dokonane zmiany będą odznaczać się kolorkem na marginesie edytora.
Stwórzmy teraz kolejną changelistę, nazwijmy ją “bugfix”, ustawiając ją na aktywną:
Widzimy, że oznaczenia na marginesie pozwalają nam odróżnić różne listy zmian. Dodatkowo kliknięcie na te oznaczenia pozwala nam m.in. na cofnięcie lub przesunięcie zmian do innej listy:
Przesunąć zmiany możemy też za pomocą przeciągnij i upuść w oknie ze zmianami. Pamiętajmy, na której changeliscie pracujemy! Aby zmienić listę na aktywną należy z jej menu kontekstowego wybrać komendę Set Active Changelist.
Praca z changelistami wymaga pewnej zmiany w myśleniu podczas pisania kodu. Każda zmiana powinna być skategoryzowana.
Przykładowe nazwy list zmian:
- logs,
- display error on every API request,
- spelling error fix in error dialog,
- new style for dialog button,
- string values,
- temporary strings pending bugfix.
Wraz z doświadczeniem w używaniu tej funkcjonalności, wyrabiamy w sobie umiejętność myślenia o kodzie w nowy sposób.
Commit
Commit to moment, w której potencjał omawianej funkcjonalności przejawia się w całej okazałości:
- changelisty związane z rozwiązaniem mogą być w różnych fazach zakończenia,
- możemy wybrać te zakończone, np. komitujemy zmiany z listy “viewModel shell”, ale zostawiamy niedziałający “login API call”,
- nie komitujemy changelist, które nie stanowią części rozwiązania albo jeszcze nie działają, zamiast “czyścić” kod przed commitem.
Android Studio pozwala nam na zakomitowanie jednocześnie tylko jednej changelisty, a domyślnie IDE wypełni nam opis commita nazwą naszej changelisty.
Możemy stąd wysnuć wniosek, że listy zmian są bytami będącymi logicznymi odpowiednikami commitów, jednak istniejącymi podczas pisania kodu, a nie podczas jego zapisywania do repozytorium.
Shelf
Półka jest miejscem, gdzie możemy “odłożyć” naszą listę zmian na później.
W celu użycia półki, włączamy menu kontekstowe dla danej changelisty i wybieramy ShelveChanges… Pojawi się dialog prawie identyczny z dialogiem do comita (czyli w pewnym sensie commitujemy zmiany na półkę).
Po przeniesieniu zmian na półkę, są one widoczne w zakładce “Shelf”.
Co istotne, podczas tej operacji zmiany z changelisty są usuwane z naszego kodu. Aby ich użyć ponownie, używamy komendy Unshelve… z menu kontekstowego.
Użycie tej komendy nie usunie tej changelisty z półki, możemy jej używać wielokrotnie.
Patch
Aby w łatwy sposób podzielić się z innymi listą zmian (aktywnych lub z półki), wystarczy z menu kontekstowego wybrać Create Patch… lub Copy as Patch to Clipboard.
Pierwsza opcja pozwala nam na eksportowanie patcha do pliku, druga jest oczywista, możemy szybko wkleić tekst patcha np. na Slacku.
W celu zaimportowania zmian z pliku, możemy użyć komendy Import Patches... z menu kotekstowego. Natomiast jeśli chcielibyśmy użyć zmian ze schowka, musimy się pofatygować do menu głównego Git -> Patch -> Apply Patch from Clipboard.
Oczywiście w obu przypadkach stworzy się osobna changelista, której nazwę możemy ustawić w kolejnym dialogu.
Funkcjonalności przenoszenia changelist na półkę i eksportowania zmian za pomocą patchy nie sposób przecenić, szczególnie w dużych projektach.
Za ich pomocą możemy stworzyć katalog rozwiązań typu:
- wyłączanie ekranu logowania,
- mockowanie odpowiedzi z API, aby zwracała daną wartość,
- symulowanie dziwnych błędów.
Następnie za pomocą patcha możemy szybko podzielić się którymś z rozwiązań ze współpracownikiem.
2. Taski
Task to w gruncie rzeczy zestaw kilku elementów:
- nazwa,
- branch,
- lista zmian,
- otwarte zakładki.
Zacznijmy od zdefiniowana nowego zadania (task).
W menu wybierzmy Tools -> Tasks & Contexts -> Open Task…, a następnie Create New Task.
Mamy tutaj kilka opcji. Kiedy zaczniemy pisać nazwę zadania, automatycznie wypełnia się też pole z nazwą changelisty do utworzenia, a także gałęzi w VCS.
Dodatkowo możemy wyczyścić obecny kontekst, czyli zamknąć wszystkie otwarte zakładki i odłożyć obecne zmiany na półkę.
Zauważmy, że stworzenie nowej listy zmian automatycznie nam dodaje odpowiedniego taska w liście zadań. Umożliwia nam to dostęp do o wiele łatwiejszej nawigacji poprzez rozwijane menu.
połączenie z issue trackerem
Możemy skonfigurować sobie issue tracker np. JIRE.
teraz po kliknięciu “Open task”…
… w menu pojawią się do wyboru przypisane do nas tickety:
Zapytaniem możemy sterować na poprzednim ekranie. Ekran tworzenia nowego taska jest teraz wzbogacony o dodatkową opcję, dzięki której możemy zaktualizować status ticketa.
3. Lokalna historia zmian
Ostatnim elementem efektywnej pracy z kodem w Android Studio, o której chciałbym wspomnieć to lokalna historia zmian.
Android Studio zapamiętuje prawie wszystkie działania, które wykonujemy. W przypadku kryzysu przydaje się umiejętność nawigacji po wydarzeniach zarejestrowanych przez nasze IDE.
Lokalna historia zmian działa w trzech kontekstach:
- zaznaczonego kodu,
- pojedynczego pliku,
- katalogu.
Analogicznie dla każdego z nich wywołujemy kontekstowe menu i wybieramy Local History -> Show History / Show History for Selection.
W przypadku zaznaczonego kodu lub pojedynczego pliku, okno ma po lewej stronie listę zmian, a po prawej różnicę w stosunku do obecnej wersji.
W przypadku zaznaczonego katalogu, okno po lewej stronie ma listę zmian, a po prawej listę zmienionych plików. Niestety utrudnia to przeglądanie zmian, które zobaczymy w nowym oknie po podwójnym kliknięciu.
Po zaznaczeniu danej zmiany możemy cofnąć się do danego miejsca w historii (“ikona revert”), jednak równie często zdarza mi się kopiować tylko interesujący mnie kawałek kodu.
Dodatkowym ułatwieniem podczas pracy z lokalną historią, jest możliwość oznaczenia obecnego stanu rzeczy za pomocą etykiety Local History –> Put Label. Nasze etykiety (a także te, które Android Studio doda automatycznie), pojawią się na liście zmian, ułatwiając nawigację.
Podsumowanie
Najciekawszym efektem stosowania powyższych funkcjonalności jest reorientacja myślenia o kodzie. Dzięki changelistom i taskom nasze zmiany stają się uporządkowane, a powiązanie tasków z issue trackerem typu JIRA zaczyna przenosić to uporządkowanie na proces tworzenia subtasków. Pewność siebie wynikająca z faktu, iż nasze zmiany są zachowywane przez IDE, pozwala nam na skupienie się na ważniejszych aspektach pracy programisty.
Zdjęcie główne artykułu pochodzi z unsplash.com.