Trzeba szukać!

anonymous person with binoculars looking through stacked books

Nie myśl o tym, czego szukasz. Myśl o tym, co znajdziesz. Dlaczego to tu jest? Czy powinno tu być? Co oznacza? To tak jak czytanie. Jeśli myślisz o «l» patrząc na «k», nie zrozumiesz żadnego słowa.

Jo Nesbø, Trzeci klucz

Korzystałem z różnych systemów kontroli wersji u wielu dostawców. Oczywiście: Github, Gitlab, Bitbucket (Stash), ale też mniej popularne jak Benstalk czy Gitea. Poza podstawowymi funkcjami hostowania repozytoriów umożliwiają mniej lub bardziej wygodne narzędzia do pracy z kodem. Od zwykłej przeglądarki plików po zaawansowane edytory i narzędzia wizualizacji historii. Jednak wszystkim brakuje jednej funkcjonalności – wyszukiwarki. Zanim podniosą się głosy, że przecież Github ma wyszukiwarkę, pozwólcie, że wyjaśnię.

Funkcje wyszukiwarki

  1. Dokładne wyszukiwanie tekstu wraz ze wszystkimi stop wordami, znakami interpunkcyjnymi itp. Dla przykładu:(%#v)\n Github vs Sourcegraph
  2. Wyszukiwanie strukturalne, np. znalezienie potencjalnych problemów z wpisu O Lokalności DateTime 
lang:java ZonedDateTime :[now] = LocalDateTime.now().atZone(:[args])
  1. Filtry wyszukiwania – możliwość zawężania do języka, nazwy pliku, repozytorium czy  gałęzi (ang. branch)
  2. Intuicyjna nawigacja

W wyżej wymienionych produktach wymienione funkcjonalności kuleją albo działają na tyle nieintuicyjnie, że nie potrafię ich użyć.

Po co szukać kodu? Czego szukać w kodzie?

Najczęściej szukam komunikatu błędu. Jeśli dostaję zgłoszenie: użytkownik zobaczył X, to najłatwiej jest wrzucić X w wyszukiwarkę i znaleźć miejsce, w którym X się pojawia. Oczywiście niektóre systemy logują nazwę pliku, linię i tym podobne, ale czasem problem tkwi w logice biznesowej, wtedy bez wyszukiwarki ani rusz. 

Czasem szukam użycia funkcji, żeby sprawdzić, jak już kiedyś ktoś z niej korzystał albo jak rozwiązywał podobny problem do mojego. Nie zawsze stackoverflow jest dobrym miejscem do szukania takich rzeczy, bo są one specyficzne dla danego projektu.

Rzadziej potrzebuję weryfikować wszystkie użycia kodu. Zdarza się to, gdy trzeba usunąć zdeprecjonowany kawałek API. Teoretycznie powinno się pisać kod tak, aby był wstecznie zgodny, jednak to kosztuje i nie zawsze się opłaca. Jeśli API jest publiczne wewnętrznie (nieudokumentowane dla użytkownika, ale dostępne dla innych części systemu), warto znaleźć wszystkie wywołania i je poprawić.

Na końcu, choć wcale nie najrzadziej, po prostu skaczę po kodzie, żeby zrozumieć, co i dlaczego się dzieje. Czytam wtedy komity, komentarze w pull requestach i przeglądam powiązane zadania (inaczej: archeologia kodu).

Moje statystyki użycia Sourcegraph

Na temat wartości wyszukiwarki kodu można przeczytać w Rozdziale 17 książki Software Engineering at Google: Lessons Learned from Programming Over Time.

Sourcegraph

Sourcegraph zainteresował mnie kilka lat temu. Potrzebowałem przejrzeć kod otwartych narzędzi i nie chciałem ich zaciągać do IDE. Ot tak po prostu, potrzebowałem coś zweryfikować u źródła. Zainstalowałem wtyczkę do przeglądarki, która rozszerza interfejs Githuba o przydatne metadane na temat danej linijki kodu i pozwala na łatwą nawigację po definicjach i użyciach funkcji/metod/klas.

Jak już wspomniałem Sourcegraph używałem do przeszukiwania otwartych repozytoriów. Ale nie każdy kod, nad którym pracuje, jest publiczny :( Dlatego kiedy potrzebowałem wyszukać coś w firmowych repozytoriach, to wciąż korzystałem z Githuba. Często kończyło się to klonowaniem repozytoriów i używaniem grepa

Wszystko lokalnie

Powyższy stan utrzymywał się do czasu, kiedy trafiłem na poniższego tweeta (niestety autor go skasował, ale zachował się na Mastodonowej kopii). 

Something I wish I had of thought of earlier. Run your own personal instance of @srcgraph & configure it to index everything. Anytime you reach for GitHub search or Google that’s feedback that a repo needs to be added to your: >always up to date, searchable, offline cache<

— @GeoffreyHuntley

Skoro Sourcegraph jest od 2 lat otwarty, a dodatkowo dostępny jest łatwy w użyciu obraz, to czemu nie postawić tego lokalnie. Bazując na doświadczeniu z indeksowania w intelliJ, bałem się, że na lokalnym komputerze nie uciągnę tego. Tym bardziej, że liczba repozytoriów w obecnej organizacji zbliżała się do tysiąca. Moje obawy okazały się bezpodstawne. Przy jednym użytkowniku, który od czasu do czasu coś wyszuka, Sourcegraph działa bez widocznej degradacji wydajności. 

docker run \
 --rm \
 --publish 7080:7080 \
 --publish 127.0.0.1:3370:3370 \
 --volume ~/.sourcegraph/config:/etc/sourcegraph \
 --volume ~/.sourcegraph/data:/var/opt/sourcegraph \
 sourcegraph/server:3.20.1

Przy pierwszym uruchomieniu skonfigurowałem w GUI wszystko, czego potrzebowałem i wyeksportowałem pliki konfiguracyjne tak, aby łatwo podbijać wersje obrazu. Sourcegraph zaciągnął i zaindeksował wszystkie repozytoria, a mi pozostało szukać.

Jak zaznacza CEO Sourcegraph grupą docelową są zespoły, a narzędzie jest przygotowane do współdzielenia pomiędzy użytkownikami. Oczywiście ma to swoje plusy – indeksujemy raz, szukamy wielokrotnie. Niestety, kiedy chce się wdrożyć takie narzędzie, trzeba podjąć decyzje, kto je będzie utrzymywał (aktualizował, monitorował) i jakie będzie miało SLA. Robiąc to lokalnie jesteśmy niezależni od firmowej polityki, a co więcej mamy dostęp offline do kodu. Co wbrew pozorom przydaje się od czasu do czasu…

https://classicprogrammerpaintings.com/post/144953638470/github-major-service-outage-georges-seurat

Alternatywy

Jest kilka podobnych projektów. Jeden z nich OpenGrok udostępnia tabelkę z porównaniem dostępnych narzędzi na rok 2018. Nie testowałem wszystkich, jednak pod względem wizualnym trochę im brakuje. Najciekawszą alternatywą nie uwzględnioną w porównaniu wydaje się Hund. Google udostępniał podobny projekt Google Code Search, który w 2012 został zamknięty i otwarty ponownie w innej formie. Obecnie przeszukiwać można Androida, Chromium i kilka projektów open source. To jak działa Google Code Search, stało się podstawą działania wspomnianego Hunda. Co ciekawe, podejście do wyszukiwania nie jest nowe. Jak napisał Russ Cox w Regular Expression Matching with a Trigram Index or How Google Code Search Worked  bazował na pracach Shannona (tego od teorii informacji), który bazował na pracach Pratta (nie tego od algorytmu KMP)

Co dalej?

Samo wyszukiwanie to nie koniec. Niedawno Sourcegraph dodał kampanie, czyli sposób na zdefiniowanie zmiany, otworzenie pull requestów w kilku repozytoriach oraz monitorowanie ich. Narzędzie bardzo ciekawe, porównywalne do Googlowych Large-Scale Changes, tyle że nie ograniczone do jednego repozytorium.


Leave a Reply