Moja firma (nazwijmy je Acme Technology) ma bibliotekę około tysiąca plików źródłowych, które pierwotnie pochodziły od jej grupy badawczej Acme Labs, inkubowanej przez kilka lat w grupie programistów, a ostatnio udostępniono garstce klientów pod nieujawnianie. Acme przygotowuje się do wydania około 75% kodu społeczności open source. Pozostałe 25% zostanie wydanych później, ale na razie albo nie jest gotowy do użytku przez klienta, albo zawiera kod związany z przyszłymi innowacjami, których muszą trzymać z dala od konkurentów.
Kod jest obecnie sformatowany za pomocą #ifdefs, które pozwalają tej samej bazie kodu współpracować z platformami przedprodukcyjnymi, które będą dostępne dla badaczy uniwersyteckich i znacznie szerszego grona klientów komercyjnych, kiedy przejdą na open source, jednocześnie będąc dostępne do eksperymentów i prototypowania oraz do testowania zgodności z przyszłą platformą. Utrzymanie jednej bazy kodu jest uważane za niezbędne dla ekonomii (i rozsądku) mojej grupy, która miałaby trudności z utrzymaniem dwóch kopii równolegle.
Pliki w naszej obecnej bazie wyglądają mniej więcej tak:
> // Copyright 2012 (C) Acme Technology, All Rights Reserved.
> // Very large, often varied and restrictive copyright license in English and French,
> // sometimes also embedded in make files and shell scripts with varied
> // comment styles.
>
>
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> #ifdef UNDER_RESEARCH
> holographicVisualization(on);
> #endif
> }
I chcielibyśmy przekonwertować je na coś takiego:
> // GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
> // Acme appreciates your interest in its technology, please contact [email protected]
> // for technical support, and www.acme.com/emergingTech for updates and RSS feed.
>
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> }
Czy istnieje narzędzie, biblioteka do analizy składni lub popularny skrypt, który może zastąpić prawa autorskie i usunąć nie tylko #ifdefs, ale także warianty takie jak #if zdefiniowane (UNDER_RESEARCH) itp.?
Kod jest obecnie w Git i prawdopodobnie byłby przechowywany gdzieś, gdzie używa Git. Czy istnieje sposób bezpiecznego łączenia repozytoriów ze sobą, abyśmy mogli skutecznie zintegrować nasze ulepszenia z wersjami open source? Porady na temat innych pułapek są mile widziane.
źródło
Odpowiedzi:
Wydaje się, że to nie byłoby zbyt trudne do napisania skryptu do analizowania preprocesory, porównać je do listy zdefiniowanych stałych (
UNDER_RESEARCH
,FUTURE_DEVELOPMENT
etc.), a jeżeli dyrektywa może być oceniana na fałszywym danym co zdefiniowany, usuń wszystko w górę do następnego#endif
.W Pythonie zrobiłbym coś takiego,
Jestem pewien, że istnieją bardziej eleganckie sposoby na zrobienie tego, ale jest to szybkie i brudne i wydaje się, że praca jest wykonana.
źródło
Myślałem o przekazaniu kodu przez preprocesor, aby rozwinąć tylko makra, a tym samym wypisać tylko interesującą część w
#ifdef
s.Coś takiego powinno działać:
Ale:
-CC
aby (w pewnym sensie) je zachować, ale nadal będziesz musiał usunąć starą informację o prawach autorskich#include
s są również rozwinięte, więc powstanie duży plik zawierający całą zawartość dołączonych plików nagłówkowychMoże istnieć sposób ograniczenia, które makra są rozwijane; jednakże proponuję tutaj podzielić rzeczy, zamiast robić (potencjalnie niebezpieczne) przetwarzanie plików (tak przy okazji, jak planowałbyś je później utrzymywać? np. przywrócić kod z wersji opensource do twojego zamkniętego źródła?).
Innymi słowy, spróbuj umieścić kod, który chcesz otworzyć, w zewnętrznych bibliotekach tak często, jak to możliwe, a następnie użyj ich tak, jak w każdej innej bibliotece, integrując się z innymi „niestandardowymi” bibliotekami o zamkniętym źródle.
Na początku może zająć trochę więcej czasu, aby dowiedzieć się, jak zrestrukturyzować rzeczy, ale jest to zdecydowanie właściwy sposób na osiągnięcie tego.
źródło
Mam rozwiązanie, ale będzie wymagało trochę pracy
pypreprocessor to biblioteka, która zapewnia preprocesor w stylu c dla Pythona, który może być również używany jako GPP (Preprocesor ogólnego przeznaczenia) dla innych typów kodu źródłowego.
Oto podstawowy przykład:
Preprocesor jest niezwykle prosty. Dokonuje przejścia przez źródło i warunkowo komentuje źródło na podstawie tego, co jest zdefiniowane.
Definicje można ustawić za pomocą instrukcji #define w źródle lub ustawiając je na liście pypreprocessor.defines.
Ustawienie parametrów wejściowych / wyjściowych pozwala jawnie zdefiniować, które pliki są otwierane / zamykane, dzięki czemu pojedynczy preprocesor może zostać skonfigurowany do przetwarzania wsadowego dużej liczby plików w razie potrzeby.
Ustawiając parametr removeMeta na wartość True, preprocesor powinien automatycznie wyodrębnić wszystkie instrukcje preprocesora, pozostawiając jedynie przetworzony kod.
Uwaga: Zwykle nie trzeba tego ustawiać jawnie, ponieważ Python automatycznie usuwa kod komentarza podczas kompilacji do kodu bajtowego.
Widzę tylko jedną obudowę krawędzi. Ponieważ chcesz wstępnie przetworzyć źródło C, możesz chcieć ustawić definicje procesora jawnie (tj. Poprzez pypreprocessor.defines) i powiedzieć mu, aby ignorował instrukcje #define w źródle. Powinno to uchronić go przed przypadkowym usunięciem wszelkich stałych, których możesz użyć w kodzie źródłowym swojego projektu. Obecnie nie ma parametru, który ustawiałby tę funkcjonalność, ale dodanie tego byłoby trywialne.
Oto prosty przykład:
Następnie źródło:
Uwaga: Oczywiście musisz znaleźć sposób ustawienia plików wejściowych / wyjściowych, ale nie powinno to być zbyt trudne.
Ujawnienie: Jestem oryginalnym autorem pypreprocesora.
Poza tym: pierwotnie napisałem to jako rozwiązanie problemu związanego z konserwacją Pythona 2k / 3x. Moje podejście polegało na zrobieniu programowania 2 i 3 w tych samych plikach źródłowych i po prostu uwzględnianie / wykluczanie różnic za pomocą dyrektyw preprocesora. Niestety odkryłem, że nie da się napisać prawdziwego czystego (tj. Nie wymaga c) preprocesora w pythonie, ponieważ lexer zaznacza błędy składniowe w niekompatybilnym kodzie, zanim preprocesor będzie miał szansę na uruchomienie. Tak czy inaczej, nadal jest przydatny w wielu okolicznościach, w tym w twojej.
źródło
Prawdopodobnie byłby to dobry pomysł
1. dodaj tagi komentarza, takie jak:
2. Napisz skrypt dla konstruktora oprogramowania open source, aby przeglądał wszystkie pliki i zamieniał tekst między znacznikami COPYRIGHT-BEGIN-TAG i COPYRIGHT-ENG-TAG
źródło
Nie zamierzam pokazywać narzędzia do konwersji bazy kodu, wiele odpowiedzi już to zrobiło. Odpowiadam raczej na twój komentarz na temat obsługi gałęzi w tym celu.
Powinieneś mieć 2 oddziały:
Preprocesory nie powinny istnieć. Masz dwie różne wersje. I ogólnie czystsza baza kodów.
Boisz się równoległego przechowywania dwóch kopii? Nie martw się, możesz się połączyć!
Jeśli dokonujesz modyfikacji w oddziale społeczności, po prostu połącz je w oddziale profesjonalnym. Git radzi sobie z tym naprawdę dobrze.
W ten sposób przechowujesz 2 zachowane kopie swojej bazy kodu. Wydanie jednego dla Open Source jest łatwe jak ciasto.
źródło