Czy powinienem przechowywać wygenerowany kod w kontroli źródła


106

To jest debata, w której biorę udział. Chciałbym uzyskać więcej opinii i punktów widzenia.

Mamy kilka klas, które są generowane w czasie kompilacji do obsługi operacji DB (w tym konkretnym przypadku z SubSonic, ale nie sądzę, że jest to bardzo ważne dla pytania). Generowanie jest ustawiane jako krok przed kompilacją w programie Visual Studio. Dlatego za każdym razem, gdy programista (lub oficjalny proces kompilacji) uruchamia kompilację, te klasy są generowane, a następnie kompilowane do projektu.

Teraz niektórzy twierdzą, że zapisanie tych klas w kontroli źródła może spowodować zamieszanie, na wypadek gdyby otrzymany kod nie pasował do tego, co zostałoby wygenerowane w twoim własnym środowisku.

Chciałbym mieć sposób na prześledzenie historii kodu, nawet jeśli jest on zwykle traktowany jako czarna skrzynka.

Jakieś argumenty lub kontrargumenty?


UPDATE: Zadałem to pytanie, ponieważ naprawdę wierzyłem, że jest jedna ostateczna odpowiedź. Patrząc na wszystkie odpowiedzi, mógłbym z dużą dozą pewności stwierdzić, że nie ma takiej odpowiedzi. Decyzja powinna być podjęta na podstawie więcej niż jednego parametru. Przeczytanie poniższych odpowiedzi może dostarczyć bardzo dobrych wskazówek dotyczących rodzajów pytań, które należy sobie zadać, podejmując decyzję w tej sprawie.

W tym momencie nie wybiorę zaakceptowanej odpowiedzi z powodów wymienionych powyżej.


1
Możesz być zainteresowany podobnym pytaniem: stackoverflow.com/questions/739391/…
mouviciel

Chciałbym powiedzieć, że w przypadku SubSonic może być interesujące utrzymanie kontroli źródła jako sposobu na łatwe śledzenie (niektórych) zmian w bazie danych, na wypadek, gdybyś nie miał innego sposobu śledzenia historii Twoja baza danych.
Earlz

1
Moim zdaniem głównym problemem jest to, że różni programiści nie uzyskują takich samych wyników podczas generowania klas. Konfiguracja do ich generowania powinna zostać zarejestrowana i zapewnić spójne kompilacje we wszystkich środowiskach programistów.
nawroth

1
Nie wiem, jak to zrobić, jednak myślę, że to pytanie powinno zostać teraz zamknięte, ponieważ jest zbyt otwarte na opinie i dyskusję bez ścisłego powiązania z określonymi systemami kontroli źródła lub określonymi typami generowanych plików.
Chris Halcrow,

To świetne pytanie, ale jest ono zbyt oparte na opiniach, jak na SO, na co wskazują liczne sprzeczne odpowiedzi oraz własny komentarz PO na ten temat.
Flimzy

Odpowiedzi:


48

Zapisanie go w kontroli źródła jest większym kłopotem niż jest warte.

Musisz zatwierdzać za każdym razem, gdy tworzysz kompilację, aby miała jakąkolwiek wartość.

Generalnie zostawiamy wygenerowany kod (idl, rzeczy jaxb itp.) Poza kontrolą źródła, gdzie pracuję i nigdy nie było to problemem


43
Nie zgadzam się z stwierdzeniem, że „za każdym razem, gdy budujesz, musisz wykonywać zatwierdzenie”. Nie powinno to powodować żadnego dodatkowego zatwierdzenia, ponieważ jedyną rzeczą, która powinna wpływać na zatwierdzenie, jest zmiana w kodzie, która tym samym zmienia wygenerowane źródło. W efekcie musisz zatwierdzić wygenerowany kod tylko wtedy, gdy już zatwierdzasz zmianę w źródle wygenerowanego kodu.
JaredPar

5
Zgadzam się z JaredPar. Również twój generator kodu może być narzędziem zewnętrznym i jeśli go zaktualizujesz, wygenerowany kod może się zmienić i dlatego może być konieczne zatwierdzenie zmian. Ale w tym przypadku naprawdę chciałbym zobaczyć zmiany w kontroli źródła.
van

Różne narzędzia mogą generować różne źródła (przynajmniej mogą różnić się komentarzami lub formatowaniem kodu). Np. Idea dodaje komentarz „wygenerowany przez pomysł”, podczas gdy Eclipse nie.
Petr Gladkikh

1
Opinia jest podzielona, ​​oznaczenie tej odpowiedzi jako odpowiedzi przekazałoby błędną wiadomość.
Espresso

34

Umieść to w kontroli kodu źródłowego. Zaleta posiadania historii wszystkiego, co piszesz, dostępnej dla przyszłych programistów, przeważa nad niewielkim bólem wynikającym z okazjonalnego odtwarzania po synchronizacji.


18
To nie jest zaleta - ponieważ kod, który go utworzył, jest sprawdzany, masz już „wszystko, co piszesz” dostępne dla przyszłych programistów.
Shane C. Mason

13
@Shane, zdecydowanie się nie zgadzam. Posiadanie kodu, który go stworzył, nie oznacza posiadania kodu. Wszelkie dodatkowe kroki, które muszą zostać uwzględnione w celu wygenerowania, są dodatkową irytacją podczas śledzenia błędu. O wiele łatwiej jest przejrzeć historię kodu, niż sprawdzić N wersji pliku i ponownie wygenerować N wersji wygenerowanego kodu.
JaredPar

10
Czasami warto mieć wygenerowane pliki w kontroli źródła. Na przykład, jeśli zaktualizujesz komponent, w tym przypadku SubSonic, możesz łatwo wykryć zmiany w wygenerowanym źródle. Może to być przydatne w śledzeniu błędów i problemów. Nie dodałbym całego wygenerowanego kodu do kontroli źródła. Czasami jest to bardzo przydatne. Większość systemów kontroli źródła pozwoli ci zrobić różnicę, aby zobaczyć, czy pliki naprawdę się zmieniły, chociaż może to bardziej proces ręczny, jeśli musisz ręcznie przywrócić pliki, mimo że jedyną zmianą jest znacznik czasu.
Ryan

18
Zgodnie z tą logiką powinieneś również sprawdzić skompilowane pliki obiektowe, biblioteki i pliki wykonywalne.
Laurence Gonsalves

9
Jakiego rodzaju generatora kodu używasz, gdzie „język oryginalny jest bez znaczenia”? Jeśli chodzi o śledzenie wersji narzędzi, których używasz do budowania każdej wersji kodu, musisz już rozwiązać ten problem dla całego łańcucha narzędzi. W końcu, jak spodziewasz się przenieść błąd do starszej wersji produktu, jeśli nie wiesz, jakiej wersji kompilatora i linkera używasz wtedy? Generator kodu nie różni się od kompilatora C ++ / Java / C #. Fakt, że możesz być w stanie odczytać jego wyjście, jest nieistotny: jego wejście jest źródłem.
Laurence Gonsalves

31

Za każdym razem, gdy chcę pokazać zmiany w drzewie źródłowym w moim osobistym repozytorium, wszystkie „wygenerowane pliki” będą widoczne jako zmienione i wymagają zatwierdzenia.

Wolałbym mieć bardziej przejrzystą listę modyfikacji, która obejmuje tylko rzeczywiste aktualizacje, które zostały wykonane, a nie zmiany generowane automatycznie.

Zostaw je, a po kompilacji dodaj „ignoruj” do każdego z wygenerowanych plików.


3
Ponadto w przypadku aktualizacji mogą wystąpić dziwne konflikty, które VCS uzna za wymagające rozwiązania, ale w rzeczywistości rozwiążą się same przy następnej kompilacji. Nie wspominając o bałaganie w dziennikach, który uważam za nawet gorszy niż bałagan w twoim lokalnym drzewie.
rmeador

5
Tam, gdzie jestem, nie pokazują się, że „zmienili się”, chyba że naprawdę się zmienili. Jeśli zostały ponownie wygenerowane, ale nadal mają tę samą zawartość, więc jedyną różnicą są daty utworzenia / modyfikacji plików, system uważa, że ​​nie uległy zmianie i wszystko jest w porządku.
Joel Coehoorn

+1 Ja tylko chcę być odpowiedzialny za to, co napisać kod I, nie jakiś kod, który został wygenerowany przez jakiegoś zestawu narzędzi, które mogą mieć problemy miał w tym czasie, że teraz są niemożliwe do powielenia (ale ktoś mógłby poświęcić dużo czasu na próby.)
dkretz

4
Widziałem narzędzia do automatycznego generowania, które aktualizują sygnaturę czasową przy każdym uruchomieniu. Przeklinam ich.
Kieveli

25

Spójrz na to w ten sposób: czy sprawdzasz pliki obiektów w kontroli źródła? Wygenerowane pliki źródłowe są artefaktami kompilacji, podobnie jak pliki obiektów, biblioteki i pliki wykonywalne. Powinny być traktowane tak samo. Większość twierdzi, że nie należy sprawdzać wygenerowanych plików obiektów i plików wykonywalnych w kontroli źródła. Te same argumenty dotyczą wygenerowanego źródła.

Jeśli potrzebujesz spojrzeć na historyczną wersję wygenerowanego pliku, możesz zsynchronizować z historyczną wersją jego źródeł i odbudować.

Wpisywanie dowolnego rodzaju wygenerowanych plików do kontroli źródła jest analogiczne do denormalizacji bazy danych. Czasami istnieją powody, aby to zrobić (zazwyczaj ze względu na wydajność), ale należy to robić z wielką ostrożnością, ponieważ utrzymanie poprawności i spójności staje się znacznie trudniejsze po zdenormalizowaniu danych.


20

Powiedziałbym, że należy unikać dodawania wygenerowanego kodu (lub innych artefaktów) do kontroli źródła. Jeśli wygenerowany kod jest taki sam dla danych wejściowych, możesz po prostu sprawdzić wersje, które chcesz porównać i wygenerować kod do porównania.


1
Do Twojej wiadomości, tutaj udostępniłem skrypt do tego porównania: stackoverflow.com/a/16754923/105137
kostmo.

17

Nazywam zasadę DRY. Jeśli masz już w repozytorium „pliki źródłowe”, które są używane do generowania tych plików kodu w czasie kompilacji, nie ma potrzeby „dwukrotnego” zatwierdzania tego samego kodu.

W ten sposób możesz również uniknąć niektórych problemów, jeśli na przykład generowanie kodu pewnego dnia się zepsuje.


15

Nie, z trzech powodów.

  1. Kod źródłowy jest wszystkim, co jest konieczne i wystarczające, aby odtworzyć migawkę aplikacji z jakiegoś obecnego lub poprzedniego punktu w czasie - nic więcej i nic mniej. Po części oznacza to, że ktoś jest odpowiedzialny za wszystko, co zostało wpisane. Generalnie jestem szczęśliwy, że jestem odpowiedzialny za kod, który piszę, ale nie za kod, który jest generowany w konsekwencji tego, co piszę.

  2. Nie chcę, aby ktoś ulegał pokusie, aby spróbować skrócić kompilację ze źródeł podstawowych za pomocą kodu pośredniego, który może być aktualny lub nie (a co ważniejsze, za który nie chcę brać odpowiedzialności). kusi niektórych ludzi, aby dali się wciągnąć w bezsensowny proces dotyczący debugowania konfliktów w kodzie pośrednim opartym na częściowych kompilacjach.

  3. Gdy przejdzie do kontroli źródła, przyjmuję odpowiedzialność za plik. to jest tam, b. jest aktualny i c. jest niezawodnie integrowalny ze wszystkim innym. Obejmuje to usunięcie go, gdy już go nie używam. Im mniej tej odpowiedzialności, tym lepiej.


14

Naprawdę uważam, że nie powinieneś ich sprawdzać.

Z pewnością każda zmiana w wygenerowanym kodzie będzie albo szumem - zmianami między środowiskami lub zmianami w wyniku czegoś innego - np. Zmiany w twojej bazie danych. Jeśli skrypty tworzenia bazy danych (lub jakiekolwiek inne zależności) znajdują się w kontroli źródła, to dlaczego potrzebujesz również wygenerowanych skryptów?


8

Ogólna zasada brzmi nie , ale jeśli wygenerowanie kodu zajmuje trochę czasu (z powodu dostępu do bazy danych, usług internetowych itp.), Możesz chcieć zapisać wersję z pamięci podręcznej w kontroli źródła i oszczędzić wszystkim bólu.

Twoje narzędzia również muszą być tego świadome i obsługiwać wyewidencjonowywanie z kontroli źródła w razie potrzeby, zbyt wiele narzędzi decyduje się na wyewidencjonowanie z kontroli źródła bez żadnego powodu.
Dobre narzędzie będzie używać wersji z pamięci podręcznej bez jej dotykania (ani modyfikowania przedziałów czasowych w pliku).

Trzeba też umieścić duże ostrzeżenie w generowanym kodzie, aby ludzie nie modyfikowali pliku, ostrzeżenie na górze nie wystarczy, trzeba je powtarzać co kilkanaście wierszy.


6

Nie przechowujemy również wygenerowanego kodu DB: ponieważ jest on generowany, możesz go pobrać dowolnie w dowolnej wersji z plików źródłowych. Przechowywanie go byłoby jak przechowywanie kodu bajtowego lub podobnego.

Teraz musisz upewnić się, że generator kodu używany w danej wersji jest dostępny! Nowsze wersje mogą generować inny kod ...


5

Zostaw to.

Jeśli wpisujesz wygenerowane pliki, robisz coś nie tak. Co złego może się różnić, to może być to, że proces kompilacji jest nieefektywne, albo coś innego, ale nie widzę go zawsze jest dobrym pomysłem. Historia powinna być powiązana z plikami źródłowymi, a nie wygenerowanymi.

Powoduje to po prostu ból głowy dla osób, które następnie próbują rozwiązać różnice, znaleźć pliki, które nie są już generowane przez kompilację, a następnie je usunąć itp.

Świat bólu czeka na tych, którzy zarejestrują wygenerowane pliki!


4

Istnieje specjalny przypadek, w którym chcesz zaewidencjonować wygenerowane pliki: kiedy może zajść potrzeba kompilacji w systemach, w których narzędzia używane do generowania innych plików nie są dostępne. Klasycznym przykładem tego, z którym pracuję, jest kod Lex i Yacc. Ponieważ tworzymy system wykonawczy, który musi budować i działać na ogromnej różnorodności platform i architektur, możemy polegać tylko na systemach docelowych, aby mieć kompilatory C i C ++, a nie na narzędziach niezbędnych do wygenerowania kodu leksykalnego / parsującego dla naszej definicji interfejsu tłumacz. Tak więc, kiedy zmieniamy naszą gramatykę, sprawdzamy wygenerowany kod, aby go przeanalizować.


2
Podobne komentarze dotyczą plików generowanych przez autoconf / automake; większość ludzi sprawdza swoje pliki ./configure i Makefile.in, mimo że są generowane - większość użytkowników (i wielu programistów) nie będzie musiała ich odbudowywać, a sprawdzając te pliki, nie potrzebujesz instalowanych autotools budować.
Stobor

1
Tak, przechowujemy nasz skrypt konfiguracyjny i wygenerowane przez nas zależności Make w kontroli wersji.
Phil Miller,

4

przyjeżdża trochę późno ... w każdym razie ...

Czy umieściłbyś plik pośredni kompilatora w kontroli wersji źródła? W przypadku generowania kodu, z definicji kod źródłowy jest wejściem generatora, podczas gdy wygenerowany kod można traktować jako pliki pośrednie między "rzeczywistym" źródłem a zbudowaną aplikacją.

Więc powiedziałbym: nie poddawaj wygenerowanego kodu pod kontrolę wersji, ale generator i jego wejście.

Konkretnie pracuję z generatorem kodu, który napisałem: nigdy nie musiałem utrzymywać wygenerowanego kodu źródłowego pod kontrolą wersji. Powiedziałbym nawet, że odkąd generator osiągnął pewien poziom dojrzałości, nie musiałem obserwować zawartości generowanego kodu, chociaż dane wejściowe (np. Opis modelu) uległy zmianie.


3

W niektórych projektach dodaję wygenerowany kod do kontroli źródła, ale to naprawdę zależy. Moja podstawowa wskazówka jest taka, że ​​jeśli wygenerowany kod jest nieodłączną częścią kompilatora, nie będę go dodawać. Jeśli wygenerowany kod pochodzi z zewnętrznego narzędzia, takiego jak w tym przypadku SubSonic, to dodałbym if do kontroli źródła. Jeśli okresowo aktualizujesz komponent, chcę poznać zmiany w wygenerowanym źródle w przypadku pojawienia się błędów lub problemów.

Jeśli chodzi o wygenerowany kod, który musi zostać zarejestrowany, najgorszym scenariuszem jest ręczne różnicowanie plików i ich przywracanie, jeśli to konieczne. Jeśli używasz svn, możesz dodać hak przed zatwierdzeniem w svn, aby odmówić zatwierdzenia, jeśli plik tak naprawdę się nie zmienił.


3

Zadaniem zarządzania konfiguracją (którego kontrola wersji jest tylko jedną częścią) jest umożliwienie wykonania następujących czynności:

  • Dowiedz się, jakie zmiany i poprawki błędów zostały wprowadzone w każdej dostarczonej kompilacji.
  • Być w stanie odtworzyć dokładnie każdą dostarczoną kompilację, zaczynając od oryginalnego kodu źródłowego. Kod wygenerowany automatycznie nie liczy się jako „kod źródłowy” niezależnie od języka.

Pierwsza z nich zapewnia, że ​​kiedy powiesz klientowi lub użytkownikowi końcowemu „błąd zgłoszony w zeszłym tygodniu został naprawiony i dodano nową funkcję”, nie wróci on dwie godziny później i powie „nie, nie ma”. Zapewnia również, że nie powiedzą „Dlaczego to robi X? Nigdy nie prosiliśmy o X”.

Drugi oznacza, że ​​kiedy klient lub użytkownik końcowy zgłosi błąd w jakiejś wersji, którą wydałeś rok temu, możesz wrócić do tej wersji, odtworzyć błąd, naprawić go i udowodnić, że to twoja poprawka wyeliminowała błąd, a nie pewne zakłócenia kompilatora i inne poprawki.

Oznacza to, że Twój kompilator, biblioteki itp. Również muszą być częścią CM.

A teraz odpowiedz na twoje pytanie: jeśli potrafisz wykonać wszystkie powyższe czynności, nie musisz rejestrować żadnych reprezentacji pośrednich, ponieważ i tak masz gwarancję uzyskania tej samej odpowiedzi. Jeśli nie możesz zrobić wszystkiego powyżej, wszystkie zakłady są wyłączone, ponieważ nigdy nie możesz zagwarantować, że zrobisz to samo dwa razy i uzyskasz taką samą odpowiedź. Więc równie dobrze możesz umieścić wszystkie swoje pliki .o pod kontrolą wersji.


2

To naprawdę zależy. Ostatecznie celem jest odtworzenie tego, co miałeś, jeśli zajdzie taka potrzeba. Jeśli jesteś w stanie dokładnie zregenerować pliki binarne, nie ma potrzeby ich przechowywania. ale musisz pamiętać, że aby odtworzyć swoje rzeczy, prawdopodobnie będziesz potrzebować dokładnej konfiguracji, z którą to zrobiłeś w pierwszej kolejności, a to oznacza nie tylko kod źródłowy, ale także środowisko kompilacji, IDE, a może nawet inne biblioteki , generatory lub inne rzeczy, w dokładnej konfiguracji (wersjach), której użyłeś.

Miałem kłopoty w projektach, w których zaktualizowaliśmy nasze środowisko kompilacji do nowszych wersji lub nawet do innych dostawców, gdzie nie mogliśmy odtworzyć dokładnie tych plików binarnych, które mieliśmy wcześniej. Jest to prawdziwy ból, gdy pliki binarne, które mają być głęboko, zależą od pewnego rodzaju hasha, szczególnie w zabezpieczonym środowisku, a odtworzone pliki w jakiś sposób różnią się z powodu aktualizacji kompilatora lub czegokolwiek innego.

Czy mógłbyś więc przechowywać wygenerowany kod: powiedziałbym, że nie. Wydane pliki binarne lub produkty dostarczane, w tym narzędzia, z których je odtworzyłeś, będę przechowywać. A potem nie ma potrzeby przechowywania ich w kontroli źródła, po prostu zrób dobrą kopię zapasową tych plików.


„to nie tylko oznacza kod źródłowy, ale także środowisko kompilacji, IDE, może nawet inne biblioteki, generatory lub inne rzeczy” \ n To wszystko, co chciałbym sprawdzić. Jeśli kompilujesz kompilator ze źródła na każdym komputerze deweloperskim w ramach tej samej kompilacji, co Twoje aplikacje (np. wpisujesz raz „make”), sprawdź źródło. Jeśli nie, sprawdź w
plikach

2

Prawidłowa odpowiedź to „To zależy”. To zależy od potrzeb klienta. Jeśli możesz przywrócić kod do konkretnej wersji i bez niego stawić czoła audytowi zewnętrznemu, nadal nie jesteś na twardym gruncie. Jako deweloperzy musimy wziąć pod uwagę nie tylko „hałas”, ból i miejsce na dysku, ale również fakt, że mamy za zadanie odgrywać rolę generowania własności intelektualnej i mogą to mieć konsekwencje prawne. Czy byłbyś w stanie udowodnić sędziemu, że jesteś w stanie odtworzyć witrynę internetową dokładnie tak, jak widział ją klient dwa lata temu?

Nie sugeruję, abyś zapisywał lub nie zapisywał plików gen'd, niezależnie od tego, w jaki sposób zdecydujesz, jeśli nie angażujesz Ekspertów Przedmiotowych do decyzji, którą prawdopodobnie nie masz.

Moje dwa centy.


Robisz interesującą uwagę i nie bierzesz osobiście głosu przeciw, po prostu ze względów praktycznych w często szybko zmieniających się środowiskach deweloperskich jest to po prostu niepraktyczne. Dlaczego w każdym razie kod generowany automatycznie miałby zawierać jakiekolwiek dane dotyczące treści lub adresu IP? Sugerowałbym, że generalnie klienci nie byliby w stanie pojąć implikacji automatycznie generowanego kodu kontrolującego źródła i prawdopodobnie nie powinno się im oferować takiej opcji. IMHO to zbyt dużo narzutów i kosztów, aby zająć się hipotetyczną i mało prawdopodobną sytuacją prawną.
Chris Halcrow,

W domenie, w której aktualnie jestem ubezpieczony nasz (bardzo duży) klient przechowuje WSZYSTKO przez minimum 10 lat. Tworzymy zaawansowane narzędzia do generowania usług WCF. Klienci zachowują wygenerowany kod, szablony, całość. Ale to jest mój klient. Chyba przegapiłeś punkt, o którym mówiłem, że „To zależy od potrzeb klienta” i „niezależnie od tego, w jaki sposób zdecydujesz, jeśli nie angażujesz Ekspertów ds. Tematycznych do decyzji, którą prawdopodobnie nie masz”. Jeśli w jakiś sposób to zła odpowiedź lub poprawi ci to samopoczucie, to cieszę się, że pomogłem. Odnieś się do „womp” w komentarzu nad moją odpowiedzią.
James Fleming,

2

Przedstawiono tu dobre argumenty za i przeciw. Dla przypomnienia, system generacji T4 buduję w Visual Studio i nasza domyślna opcja out-of-the-box powoduje, że wygenerowany kod jest sprawdzany. Musisz trochę ciężej popracować, jeśli wolisz nie rejestrować.

Dla mnie kluczową kwestią jest różnicowanie generowanych danych wyjściowych, gdy aktualizowane jest wejście lub sam generator.

Jeśli nie masz wpisanych danych wyjściowych, musisz wykonać kopię całego wygenerowanego kodu przed aktualizacją generatora lub modyfikacją danych wejściowych, aby móc porównać to z danymi wyjściowymi z nowej wersji. Myślę, że jest to dość żmudny proces, ale po sprawdzeniu danych wyjściowych wystarczy porównać nowe dane wyjściowe z repozytorium.

W tym miejscu rozsądnie jest zapytać „Dlaczego przejmujesz się zmianami w generowanym kodzie?” (Szczególnie w porównaniu z kodem obiektowym). Uważam, że jest kilka kluczowych powodów, które wynikają raczej z obecnego stanu wiedzy, a nie z jakiegoś nieodłącznego problemu.

  1. Tworzysz odręczny kod, który ściśle zazębia się z wygenerowanym kodem. W dzisiejszych czasach tak nie jest w przypadku plików obj. Kiedy generowany kod się zmienia, niestety dość często zdarza się, że jakiś odręczny kod musi się zmienić, aby pasował. Ludzie często nie obserwują wysokiego stopnia zgodności wstecznej z punktami rozszerzalności w wygenerowanym kodzie.

  2. Wygenerowany kod po prostu zmienia swoje zachowanie. Nie tolerowałbyś tego ze strony kompilatora, ale uczciwie mówiąc, generator kodu na poziomie aplikacji jest ukierunkowany na inny obszar problemu z szerszym zakresem akceptowalnych rozwiązań. Ważne jest, aby sprawdzić, czy przyjęte przez Ciebie założenia dotyczące poprzedniego zachowania są teraz zepsute.

  3. Po prostu nie ufasz w 100% wynikom generatora od wydania do wydania. Narzędzia generatora mają dużą wartość, nawet jeśli nie są one budowane i utrzymywane z rygorem dostawcy kompilatora. Wersja 1.0 mogła być całkowicie stabilna dla twojej aplikacji, ale być może 1.1 ma teraz kilka błędów dla twojego przypadku użycia. Alternatywnie zmieniasz wartości wejściowe i stwierdzasz, że ćwiczysz nowy element generatora, którego wcześniej nie używałeś - potencjalnie możesz zostać zaskoczony wynikami.

Zasadniczo wszystkie te rzeczy sprowadzają się do dojrzałości narzędzi - większość generatorów kodu aplikacji biznesowych nie jest tak bliska, jak kompilatory, a nawet narzędzia na poziomie lex / yacc od lat.


2

Obie strony mają słuszne i rozsądne argumenty i trudno jest zgodzić się na coś powszechnego. Systemy kontroli wersji (VCS) śledzą pliki, które programiści w nim umieszczają, i zakładają, że pliki w VCS są ręcznie tworzone przez programistów, a programiści są zainteresowani historią i zmianami między dowolnymi wersjami plików. To założenie wyrównuje dwie koncepcje: „Chcę pobrać ten plik, kiedy będę pobierać”. i „Interesuje mnie zmiana tego pliku”.

Teraz argumenty obu stron można przeformułować w ten sposób:

  • „Chcę uzyskać wszystkie te wygenerowane pliki podczas realizacji transakcji, ponieważ nie mam narzędzia do ich generowania na tym komputerze”.
  • „Nie powinienem umieszczać ich w VCS, ponieważ nie interesuje mnie zmiana tego pliku”.

Na szczęście wydaje się, że te dwa wymagania nie są ze sobą zasadniczo sprzeczne. Przy pewnym rozszerzeniu obecnych VCS powinno być możliwe posiadanie obu. Innymi słowy, to fałszywy dylemat. Jeśli się chwilę zastanowić, nietrudno zdać sobie sprawę, że problem wynika z założenia, jakie trzymają VCS. Systemy VCS powinny odróżniać pliki, które są ręcznie tworzone przez programistów, od plików, które nie są ręcznie tworzone przez programistów, ale po prostu znajdują się w tym VCS. W przypadku pierwszej kategorii plików, którą zwykle nazywamy plikami źródłowymi (kodem), systemy VCS wykonały teraz świetną robotę. W przypadku tej drugiej kategorii VCS nie miały jeszcze takiej koncepcji, o ile wiem.

Podsumowanie

Weźmy git jako jeden przykład, aby zilustrować, co mam na myśli.

  • git status nie powinien domyślnie wyświetlać wygenerowanych plików.
  • git commit powinien zawierać wygenerowane pliki jako migawkę.
  • git diff nie powinien domyślnie wyświetlać wygenerowanych plików.

PS

Jako obejście można zastosować haki Git, ale byłoby wspaniale, gdyby git obsługiwał je natywnie. gitignorenie spełnia naszych wymagań, ponieważ zignorowane pliki nie trafią do VCS.enter code here


1

Argumentowałbym za. Jeśli korzystasz z procesu ciągłej integracji, który sprawdza kod, modyfikuje numer kompilacji, tworzy oprogramowanie, a następnie je testuje, to prostsze i łatwiejsze jest posiadanie tego kodu jako części repozytorium.

Ponadto jest to nieodłączna część każdej „migawki”, którą wykonujesz z repozytorium oprogramowania. Jeśli jest częścią oprogramowania, powinien być częścią repozytorium.


5
Uwielbiam jazdę przez -1. Jeśli się nie zgadzasz, nie głosuj za tym - zagłosuj pod inne odpowiedzi. Zachowaj głosy przeciwne dla złej odpowiedzi. To jest subiektywne pytanie.
womp

1

Powiedziałbym, że tak, chcesz go poddać kontroli źródła. Z punktu widzenia zarządzania konfiguracją WSZYSTKO, co jest używane do tworzenia kompilacji oprogramowania, musi być kontrolowane, aby można było je odtworzyć. Rozumiem, że wygenerowany kod można łatwo odtworzyć, ale można argumentować, że nie jest to to samo, ponieważ data / znaczniki czasu będą różne w obu kompilacjach. W niektórych obszarach, takich jak rząd, często tak się dzieje.


2
Czy wpisujesz swoje pliki obiektowe (.o)?
KeyserSoze

1

Generalnie wygenerowany kod nie musi być przechowywany w kontroli źródła, ponieważ historię wersji tego kodu można prześledzić na podstawie historii wersji kodu, który go wygenerował!

Jednak wygląda na to, że OP używa wygenerowanego kodu jako warstwy dostępu do danych aplikacji, zamiast ręcznie ją pisać. W takim przypadku zmieniłbym proces budowania i przekazałbym kod do kontroli źródła, ponieważ jest to krytyczny składnik kodu wykonawczego. Eliminuje to również zależność od narzędzia do generowania kodu z procesu kompilacji na wypadek, gdyby programiści musieli użyć innej wersji narzędzia dla różnych gałęzi.

Wygląda na to, że kod wystarczy wygenerować tylko raz, a nie przy każdej kompilacji. Gdy programista musi dodać / usunąć / zmienić sposób, w jaki obiekt uzyskuje dostęp do bazy danych, kod powinien zostać wygenerowany ponownie, tak jak przy ręcznych modyfikacjach. Przyspiesza to proces budowania, pozwala na ręczne optymalizacje warstwy dostępu do danych, a historia warstwy dostępu do danych jest zachowywana w prosty sposób.


Nie zgadzam się. Jeśli zrobisz to ręcznie, zostanie zepsuty i nikt nie zauważy, dopóki nie nadejdzie czas, aby go ponownie uruchomić. Jeśli jest generowany codziennie na twoich serwerach kompilacji (i na wszystkich komputerach programistów, gdy wykonują „czystą” kompilację), nie będziesz zaskoczony.
KeyserSoze

Jeśli kod warstwy dostępu do danych zostanie wprowadzony do kontroli źródła, nie powinno być żadnych niespodzianek, ponieważ ludzie będą zmuszeni do aktualizacji kodu. Jeśli zdarzy się, że ktoś zmieni wersję narzędzia do generowania kodu na maszynie budującej, a programiści mają stare wersje na swojej maszynie deweloperskiej (być może inna gałąź kodu), będą bóle głowy. Sugeruję, aby usunął etap generowania kodu z procesu kompilacji, ponieważ nie są opiekunami generatora kodu.
benson

1

Kończy mi się (niestety) poddanie wielu źródeł pochodnych kontroli źródła, ponieważ pracuję zdalnie z ludźmi, którym nie przeszkadza skonfigurowanie odpowiedniego środowiska kompilacji lub które nie mają umiejętności źródła pochodne są zbudowane dokładnie poprawnie. (A jeśli chodzi o narzędzia automatyczne Gnu, sam jestem jedną z tych osób! Nie mogę pracować z trzema różnymi systemami, z których każdy działa z inną wersją narzędzi automatycznych - i tylko z tą wersją).

Ten rodzaj trudności prawdopodobnie dotyczy raczej projektów typu open source w niepełnym wymiarze godzin, wolontariuszy niż płatnych projektów, w których osoba opłacająca rachunki może nalegać na jednolite środowisko kompilacji.

Robiąc to, w zasadzie zobowiązujesz się do tworzenia plików pochodnych tylko w jednej witrynie lub tylko w odpowiednio skonfigurowanych witrynach. Twoje pliki Makefile (lub cokolwiek innego) powinny być skonfigurowane tak, aby zauważały, gdzie są uruchomione i powinny odmawiać ponownego pobierania źródeł, chyba że wiedzą, że działają w bezpiecznym miejscu kompilacji.


1

Jeśli jest częścią kodu źródłowego, powinien zostać poddany kontroli źródła niezależnie od tego, kto lub co go generuje. Chcesz, aby kontrola źródła odzwierciedlała bieżący stan systemu bez konieczności jego ponownego generowania.


„bez konieczności regeneracji”. więc sprawdzasz skompilowane pliki binarne? Czy sprawdzasz również wersję platformy docelowej? Ta strategia nie będzie dobrze skalowana. :(
dss539

1
I to daje mi głos negatywny? Oczywiście nie sprawdzasz skompilowanych plików binarnych (chyba że pochodzą z bibliotek innych firm), ponieważ można je ponownie wygenerować z kodu źródłowego. Mówiłem o konieczności ponownego generowania wygenerowanego kodu, a nie plików binarnych. Ale hej, jeśli chcesz źle zinterpretować to, co mówię, to śmiało ...
mezoid

Ta odpowiedź nie była warta negatywnej opinii! Przynajmniej wydaje się rozsądne umieszczenie wygenerowanego kodu w SC (być może w wyraźnie określonym miejscu), aby przynajmniej można było porównać hash kodu używanego do wygenerowania obiektu z nowym kodem, który zamierzasz wygeneruj dla nowej kompilacji. Ciekawe, jak polaryzujące jest to pytanie.
rp.

1

Absolutnie miej wygenerowany kod w kontroli źródła z wielu powodów. Powtarzam to, co wiele osób już powiedziało, ale są pewne powody, dla których bym to zrobił

  1. Dzięki plikom kodów w kontroli źródła potencjalnie będziesz w stanie skompilować kod bez korzystania z kroku wstępnego kompilacji programu Visual Studio.
  2. Kiedy robisz pełne porównanie dwóch wersji, dobrze byłoby wiedzieć, czy wygenerowany kod zmienił się między tymi dwoma tagami, bez konieczności ręcznego sprawdzania.
  3. Jeśli sam generator kodu się zmieni, będziesz chciał się upewnić, że zmiany w wygenerowanym kodzie odpowiednio się zmieniają. tj. jeśli twój generator się zmieni, ale wyjście nie powinno się zmienić, wtedy kiedy przejdziesz do zatwierdzenia swojego kodu, nie będzie różnic między tym, co zostało wcześniej wygenerowane, a tym, co znajduje się w wygenerowanym kodzie teraz.

1
A sam generator kodu nie jest objęty kontrolą źródła, ponieważ ...?
Jeffrey Hantin

@Jeffrey: Nigdy nie powiedziałem, że generator kodu nie jest pod kontrolą źródła.
Joe Enos

Wiem, tylko się drażnię. :-) Zauważyłem, że wiele generatorów kodu opartych na CodeDom lubi generować swoje dane wyjściowe w losowej kolejności, więc dla powtarzalności (a tym samym możliwości łatwego stwierdzenia, czy wygenerowany kod zmienia się od uruchomienia do uruchomienia). napisałem procedurę, która sortuje zawartość a CodeCompileUnitdo porządku kanonicznego.
Jeffrey Hantin

0

Pozostawiłbym wygenerowane pliki poza drzewem źródłowym, ale umieściłbym je w osobnym drzewie kompilacji.

np. przepływ pracy

  1. pobieranie / wyrejestrowywanie / modyfikowanie / łączenie źródła normalnie (bez żadnych wygenerowanych plików)
  2. W odpowiednich przypadkach sprawdź drzewo źródłowe do czystego drzewa kompilacji
  3. Po kompilacji, sprawdź wszystkie „ważne” pliki („prawdziwe” pliki źródłowe, pliki wykonywalne + wygenerowany plik źródłowy), które muszą być obecne do celów audytowych / prawnych. Daje to historię całego odpowiedniego wygenerowanego kodu + plików wykonywalnych + cokolwiek, w czasie przyrostów, które są związane z wydaniami / testowymi migawkami itp. I oddzielone od codziennego rozwoju.

Prawdopodobnie w Subversion / Mercurial / Git / etc są dobre sposoby na powiązanie historii prawdziwych plików źródłowych w obu miejscach.


0

Wygląda na to, że po obu stronach są bardzo mocne i przekonujące opinie. Zalecałbym przeczytanie wszystkich najczęściej głosowanych odpowiedzi, a następnie podjęcie decyzji, jakie argumenty mają zastosowanie w Twoim konkretnym przypadku.

UPDATE: Zadałem to pytanie, ponieważ naprawdę wierzyłem, że jest jedna ostateczna odpowiedź. Patrząc na wszystkie odpowiedzi, mógłbym z dużą dozą pewności stwierdzić, że nie ma takiej odpowiedzi. Decyzja powinna być podjęta na podstawie więcej niż jednego parametru. Przeczytanie innych odpowiedzi może dostarczyć bardzo dobrych wskazówek co do rodzajów pytań, które należy sobie zadać, podejmując decyzję w tej kwestii.

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.