Strategia rozgałęziania i wersjonowania bibliotek współdzielonych


12

Te posty wydają się powiązane, ale mój mózg zaczyna się topić, próbując to przemyśleć: P.

Mój pracodawca właśnie zaczął korzystać z kontroli źródła, przede wszystkim dlatego, że zanim zatrudnili więcej programistów, „repozytorium” było dyskiem twardym samotnego programisty, który pracuje głównie z domu. Cały napisany przez niego kod .NET został masowo sprawdzony i istnieje wiele zduplikowanych funkcji (czytaj: kopiuj-wklej). Obecnie nasz system SCM to gloryfikowana kopia zapasowa.

Chciałbym pobrać część powielonego kodu do bibliotek współdzielonych. Oryginalne repozytorium pozostawiam w spokoju, aby niczego nie zepsuć - możemy przesuwać i / lub refaktoryzować istniejący kod w razie potrzeby. Więc skonfigurowałem repozytorium tylko dla nowego kodu, w tym bibliotek.

Mój problem dotyczy wersjonowania bibliotek bez nadmiernego nakładania się na nas: przyznając, że potrzebujemy bardziej spójnego podejścia, z większą liczbą programistów piszących bardzo podobny kod, zarządzanie i inni deweloperzy są otwarci na reorganizację, ale prawdopodobnie nie będzie zejdź dobrze, jeśli rozwiązanie zacznie wpływać na wydajność.

Idealnym rozwiązaniem w moim obsesyjnym umyśle jest tworzenie bibliotek osobno, a każdy projekt zależny jest budowany na podstawie świadomie wybranych, zgodnych wersji. W ten sposób wiemy dokładnie, którzy klienci mają wersje, które biblioteki, mogą bardziej niezawodnie odtwarzać błędy, utrzymywać niezależne gałęzie wydań dla produktów i bibliotek oraz nie przerywać sobie nawzajem projektów podczas zmiany kodu współdzielonego.

To sprawia, że ​​aktualizacja bibliotek jest uciążliwa, szczególnie dla programistów pracujących z domu. Oczekuję, że biblioteki szybko się zmienią, przynajmniej początkowo, gdy (w końcu) połączymy wspólne elementy. Całkiem możliwe, że całkowicie się nad tym zastanawiam i dobrze byłoby po prostu zbudować wszystko w oparciu o najnowsze zatwierdzenia biblioteki, ale chciałbym być przynajmniej przygotowany na dzień, w którym zdecydujemy, że niektóre komponenty muszą być niezależnie wersjonowane i Rozpowszechniane. Fakt, że niektóre biblioteki będą musiały być zainstalowane w GAC, sprawia, że ​​wersja jest szczególnie ważna.

Więc moje pytanie brzmi: czego mi brakuje? Wydaje mi się, że skupiłem się na jednym rozwiązaniu i teraz próbuję znaleźć odmiany, które sprawią, że zmiany będą płynniejsze. Jakie strategie zastosowałeś wcześniej do rozwiązania tego rodzaju problemu? Zdaję sobie sprawę, że to pytanie jest wszędzie; Zrobię co w mojej mocy, aby oczyścić i wyjaśnić wszelkie wątpliwości.

I chociaż bardzo chciałbym korzystać z Mercurial, już wydaliśmy pieniądze na scentralizowany komercyjny SCM (Vault), a zmiana nie jest opcją. Poza tym myślę, że tutaj chodzi o coś głębszego niż wybór narzędzia kontroli wersji.


koszt stały jest zatopiony
alternatywnie

Odpowiedzi:


1

Pochwalam twoją inicjatywę. Powinno to przynieść szereg korzyści dla organizacji podczas jej wdrażania. Chciałbym przenieść kod zamiast go skopiować. Posiadanie kopii prawdopodobnie spowoduje niezgodne zmiany, które należy rozwiązać.

Pojawi się pewien ból, gdy biblioteki zostaną opracowane i ustabilizowane. Gdy to nastąpi, korzyści nadejdą. Pamiętaj, że interfejsy do biblioteki są zasadniczo umową z projektami współpracującymi z umową. Zaletą usuwania starych interfejsów może być możliwość ustalenia, czy są one używane.

Podczas gdy biblioteki się stabilizują, uzyskanie nowych bibliotek powinno prawdopodobnie stanowić część procesu aktualizacji kodu. Możesz zaplanować zatwierdzanie zmian w bibliotece. Ogłoszenie przeniesionego kodu może pomóc w ograniczeniu sprzecznych zmian.

Biblioteki należy traktować jako osobne projekty i jak najszybciej ustabilizować. Po ich ustabilizowaniu (szczególnie interfejsach) powinno być łatwiej zintegrować zmiany z innymi projektami. Nowe biblioteki powinny działać ze starym kodem. Oznacz stabilne wydania biblioteki własnym identyfikatorem wydania. Spróbuj traktować biblioteki tak, jak biblioteki stron trzecich.


6

Kod współdzielony między projektami należy traktować jako projekty same w sobie. Muszą być traktowane z taką samą starannością jak biblioteki stron trzecich. Nie ma innego wyjścia.

Jeśli nie możesz zmusić grupy do przyjęcia strategii dotyczącej współdzielonego kodu, możesz go zaadaptować za pomocą nowoczesnych narzędzi do zarządzania kodami źródłowymi, takich jak Mercurial lub GIT, nawet jeśli nie jest to SCM, którego Twoja firma oficjalnie używa. Z niewielką ostrożnością dwa SCM mogą korzystać z tego samego katalogu roboczego, po prostu każąc zignorować wewnętrzne pliki drugiego. Używałbyś jednego SCM do codziennej pracy, a firmowego do integracji.

W każdym razie musisz decydować o tym, kiedy zaktualizować katalog roboczy za pomocą modyfikacji wprowadzonych przez inne projekty w udostępnionym kodzie. Powinny się to zdarzyć tylko wtedy, gdy jesteś gotowy poradzić sobie z pojawiającymi się niezgodnościami; w przeciwnym razie twoja praca może stać się niestabilna poza wykonalnym.


4

Jeśli masz możliwość podzielenia ich na osobne projekty „modułowe”, przyjąłbym to podejście. Jedną z rzeczy, o które należy się martwić, jest łączenie kodów. Powodowałbyś oddzielenie obaw poprzez ich zerwanie, co jest dobrą praktyką.

Niektóre korzyści:

  1. Łatwiejsze debugowanie każdego modułu.
  2. Szybsze cykle kompilacji (brak przebudowy bibliotek, które nie uległy zmianie)
  3. Gdy coś zadziała, jest mniej prawdopodobne, że go zepsujesz, zmieniając inny obszar poza tym modułem (nie 100%, ale zmniejszasz szanse).
  4. Łatwiej jest zerwać zadania, jeśli nie jest to duży współzależny bałagan.
  5. Szybsza dystrybucja mniejszych elementów po naprawieniu jednej biblioteki (duży powód, dla którego masz pliki .dll / .so).

Mam jedno pytanie dotyczące tej części:

„Idealnym rozwiązaniem w moim obsesyjnym umyśle jest tworzenie bibliotek osobno, a każdy zależny projekt opiera się na świadomie wybranych, zgodnych wersjach”.

Czy statycznie łączysz cały projekt? Jeśli tak, prowadziłoby to do: 6. Zmniejszenia niepotrzebnego wzdęcia kodu.

Niektóre negatywne:

  1. Jeśli projekt jest mały, dodajesz złożoność tam, gdzie nie jest potrzebny.
  2. Rozgałęzienie wielu modułów może przekształcić się w problem konserwacji w przypadku naprawdę dużych projektów. Nie znam „Vault”, więc nie jestem pewien, czy ich operacje rozgałęziania są dobre czy złe.

Jest to kod C #, więc jest to „nie” dla statycznego linkowania w jego zwykłym znaczeniu. Sklepienie jest jak Subversion, pre-1.5: PI czekał tak chętnie do śledzenia korespondencji seryjnej w SVN, myśląc, że jestem w niebie, kiedy w końcu przyjechaliśmy. Potem znalazłem DVCS.
shambulator

1

W tej chwili wygląda na to, że masz jedną bazę kodu wbudowaną jednocześnie w jeden cel. Prawdopodobnie masz nie więcej niż pięciu programistów. Naprawdę nie widzę użyteczności zbytniego rozdzielania bibliotek. Zmienisz przepływ pracy z kodu -> kompiluj -> uruchom na kod -> kompiluj -> kopiuj DLL -> kompiluj -> uruchom ... ick.

Niektóre firmy (Google i Amazon) mają wystarczającą infrastrukturę do rozwoju, że tworzenie oddzielnych bibliotek jest dość bezbolesne. Infrastruktura zapewniająca bezbolesność obejmuje sposób określania wersji bibliotek, które znajdują się w SCM (który prawdopodobnie masz), sposób określania wersji zależności, które znajdują się w SCM, serwer kompilacji, który może to zrozumieć i poprawnie skompilować wszystko oraz sposób na pobranie odpowiednich artefaktów kompilacji z serwera kompilacji i lokalnego obszaru roboczego. Wątpię, czy to masz.

Bez tej infrastruktury oddzieliłbym projekt, gdy zachodzi jedna z następujących sytuacji:

  • W zależności od tej biblioteki masz wiele produktów lub różnych aplikacji
  • Pracujesz wyłącznie na tych bibliotekach przez kilka dni
  • Funkcjonalność biblioteki jest bardzo niezależna od wszystkiego, co jest związane z biznesem (na przykład opakowania wokół interfejsów API specyficznych dla platformy)
  • Czasy kompilacji połączonego projektu stają się zbyt duże

Martwi mnie budowanie tej infrastruktury, gdy masz dużo projektów, a niektórzy mają dedykowanych programistów i niezależne cykle wydawania.

To, co możesz i powinieneś teraz zrobić, to skonfigurować serwer kompilacji dla niezawodnych, powtarzalnych kompilacji i upewnić się, że możesz znaleźć wersję źródłową z danego pliku wykonywalnego. Wygląda na to, że używasz platformy .NET; skonfigurowanie CruiseControl.NET w celu wstawienia ciągu wersji, w tym numeru wersji, jest bardzo proste.

Gdy masz już serwer kompilacji, rozdzielenie biblioteki będzie prawie polegało na przeniesieniu jej do Vault, dodaniu kolejnego celu w CC.NET i skopiowaniu wynikowej biblioteki DLL do folderu biblioteki głównego projektu i zatwierdzeniu jej. Łatwiej po stronie SCM niż codzienny rozwój.


1

Mercurial ma funkcję o nazwie podrepozytoria. Niedawno przeczytałem tego bloga z Kiln wyjaśniając, jak działają.

Zasadniczo łączysz swój projekt z określoną wersją repozytorium biblioteki. Możesz aktualizować bibliotekę, ile chcesz, bez przerywania zależnych projektów. Kiedy będziesz gotowy, możesz włączyć nowe funkcje biblioteki do swojego projektu i poradzić sobie z każdym uszkodzeniem. Różne projekty mogą łączyć się z różnymi wersjami biblioteki, więc nie wszystkie muszą być zsynchronizowane i używać tej samej wersji biblioteki.

Może Vault ma podobną funkcję.


1

Do każdego modułu w SC dodaliśmy plik metadanych, który wskazuje nazwę wszystkich pozostałych modułów, od których zależy. Produkt będzie miał drugi plik metadanych wskazujący, która wersja każdego modułu zależnego jest wymagana dla produktu. Ponadto jest to narzędzie do analizy plików metadanych, sprawdzenia wszystkich wymaganych modułów i wygenerowania projektu dla naszego IDE.

Dzięki temu nasze kompilacje są zawsze odtwarzalne, a prawidłowe pliki nagłówków są zawsze udostępniane między komponentami. Inną złożoność można nakładać w miarę potrzeby. Mamy narzędzia, które mogą teraz generować raporty na temat różnic między dowolnymi dwoma kompilacjami produktu, określając zmienione pliki źródłowe, komentarze do odprawy, komentarze do wersji, autorów, we wszystkich niezależnych modułach w SC. Otrzymujemy fenomenalne ponowne użycie z naszej bazy kodu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.