Kontrola wersji i osobisty plik konfiguracyjny

36

Nasz projekt wykorzystuje specyficzny dla użytkownika plik konfiguracyjny. Ten plik nie jest obecnie objęty kontrolą wersji, ponieważ jest różny dla każdego użytkownika. Problem polega na tym, że za każdym razem, gdy programista dodaje nowy moduł, który wymaga konfiguracji lub zmienia nazwę istniejących modułów, inni programiści otrzymują błędy, ponieważ ich prywatne pliki konfiguracyjne nie są aktualizowane.

Aby rozwiązać problem, pomyśleliśmy o pracy z dwoma plikami konfiguracyjnymi: domyślnym / globalnym plikiem konfiguracyjnym, który będzie podlegał kontroli wersji i będzie regularnie aktualizowany przez każdego programistę, który dodaje nowy moduł, oraz prywatny plik konfiguracyjny, który będzie przechowywany kontroli wersji i będzie zawierać tylko zmiany specyficzne dla użytkownika.

Jednak nadal wydaje się to rozwiązaniem ad hoc.

Czy możesz zaproponować lepsze rozwiązanie?

Czym zajmują się specjaliści?

Erel Segal-Halevi
źródło
4
Boggle ... Dlaczego, u licha, pozwalasz nawet programistom zmieniać nazwy modułów i przerywać konfigurację klienta w dowolnym momencie innym niż ważna aktualizacja ?
Mark Booth
@jk tak, jest jeszcze lepsze dopasowanie: stackoverflow.com/questions/1974886/...
Erel Segal-Halevi
Jestem zdziwiony. Jak to nie jest problem podczas instalowania aktualizacji.
Joshua
6
To wcale nie jest rozwiązanie ad hoc. Podstawowy plik konfiguracyjny znajduje się w kontroli wersji, przesłonięty zgodnie z wymaganiami specyficznych dla użytkownika plików konfiguracyjnych. Oczywiście ilość konfiguracji specyficznej dla użytkownika musi zostać zminimalizowana, ale pewna niewielka ilość może być nieunikniona.
William Payne

Odpowiedzi:

22

Chociaż masz już kilka dobrych odpowiedzi, w większości z nich brakuje podstawowej przyczyny problemu: pliki konfiguracyjne użytkownika wydają się zawierać więcej niż tylko informacje specyficzne dla użytkownika, ale zawierają także (być może zbędne) informacje, które są pod kontrolą wersji w innym miejscu , prawdopodobnie w różnych plikach, takich jak nazwy modułów.

Mogę wymyślić tutaj dwa możliwe rozwiązania:

  • spróbuj rygorystycznie oddzielić te informacje. Na przykład nie używaj żadnych nazw modułów w konfiguracji użytkownika. Użyj numerów identyfikacyjnych (na przykład GUID), aby odwoływać się do modułów, i niech te numery identyfikacyjne nigdy się nie zmieniają po przypisaniu do modułu. Oczywiście ma to pewną wadę, ponieważ pliki konfiguracyjne użytkownika tracą część swojej prostoty, jaką mogą mieć teraz. Być może będziesz musiał utworzyć narzędzie GUI do edycji plików konfiguracyjnych zamiast zwykłego edytora tekstowego.

  • nadaj formatowi pliku konfiguracyjnego numer wersji, a gdy zmieni się coś w rodzaju nazwy modułu, przypisz mu nowy numer wersji. Następnie możesz dostarczyć skrypt aktualizujący, który sprawdza numery wersji, a jeśli plik konfiguracyjny nie jest aktualny, zmienia wszystkie znalezione w nim nazwy modułów, a następnie zwiększa numer wersji. Można to zautomatyzować, aby proces aktualizacji nie przeszkadzał kolegom z zespołu w ich codziennej pracy.

EDYCJA: po ponownym przeczytaniu twojego ogłoszenia, myślę, że twoje domniemane rozwiązanie jest rozsądne, dopóki dodawane są nowe moduły, ale nie są zmieniane ich nazwy. To, co napisałem powyżej, pozwoli później zmienić nazwy modułów lub strukturę konfiguracji istniejących modułów. Ale jeśli tego nie potrzebujesz, trzymałbym się najprostszego rozwiązania.

Doktor Brown
źródło
11

To rozsądne rozwiązanie.

Potrzebujesz sposobu na określenie początkowych wartości dowolnych nowych elementów konfiguracji. Trzeba je gdzieś przechowywać, a oczywistym wyborem jest globalny plik konfiguracyjny tylko do odczytu.

Następnie, gdy każdy użytkownik zmieni swoją osobistą konfigurację, zapisujesz te zmiany w lokalnej kopii.

Twój kod będzie musiał najpierw przeczytać konfigurację globalną, a także konfigurację użytkownika, aby zastąpić zmienione wartości. Będzie to o wiele prostsze niż odczytanie lokalnego, a następnie próba ustalenia, które nie zostały ustawione i dlatego trzeba je odczytać z pliku ustawień globalnych.

Jeśli używasz czegoś takiego jak XML do przechowywania, nie musisz się martwić obsługą sprawy, w której usuwasz ustawienia. Nie zostaną poproszeni o kopię pliku przez użytkowników, a jeśli odtworzysz plik podczas zapisywania, zostaną one usunięte przy pierwszym użyciu aplikacji po zmianie.

ChrisF
źródło
3

Mamy dość interesujące rozwiązanie, jesteśmy przede wszystkim programistami PHP, więc używamy Phing, który umożliwia tworzenie automatycznych zadań napisanych w PHP, więc zamiast wykonywać naszą zwykłą aktualizację svn, wykonujemy „aktualizację phing”, która wywołuje aktualizację svn, a następnie zastępuje nasze config odpowiednimi zmiennymi, na przykład config:

$db_user = "${test.db_user}";

Tak więc wszystkie pliki konfiguracyjne są wersjonowane z tą interesującą składnią, a następnie generujemy adhoc, niewersjonowany plik konfiguracyjny dla mojej konkretnej instancji, który zastępuje te „zmienne” niewersjonowanymi ustawieniami określonymi w niewersjonowanych plikach ini. W ten sposób możemy modyfikować pliki specyficzne dla użytkownika i wprowadzać zmiany w innych kopiach roboczych.

Dan LaManna
źródło
2

Program powinien mieć domyślne ustawienie kodu, gdy wartość nie zostanie znaleziona w pliku konfiguracyjnym. W ten sposób, gdy dodawane są nowe rzeczy, nie ulegnie awarii, ścieżka uaktualnienia będzie gładsza, a użytkownicy będą mieli awarię, gdy zepsują plik konfiguracyjny.

Kolejnym bardziej złożonym przykładem może być uruchomienie programu lub inny kluczowy punkt, otwarcie pliku konfiguracyjnego za pomocą modułu inicjującego i dodanie brakujących ustawień domyślnych, ale wydaje się to dość trudne.

Bill Leeper
źródło
+1 za wspomnienie, że nie jest to tylko problem dla programistów, ale ogólny problem z wdrażaniem.
śleske
2

Wpisz numer wersji do osobistego pliku konfiguracyjnego (numer wersji formatu pliku konfiguracyjnego).

Sprawdź, czy kod przetwarzający osobisty plik konfiguracyjny sprawdza numer wersji, a jeśli jest nieaktualny, uruchom procedurę aktualizacji. Zasadniczo każdy, kto dokona zmiany, która zniszczy istniejące pliki konfiguracyjne, musi podnieść numer wersji formatu pliku konfiguracyjnego i napisać procedurę aktualizacji plików konfiguracyjnych poprzedniej wersji (zmiana nazw sekcji itp.) I ponowne zapisanie im.

Prawdopodobnie i tak będziesz potrzebować takiego procesu dla użytkowników końcowych, więc równie dobrze możesz go użyć, aby ułatwić życie programistom.

Carson63000
źródło
1

Zazwyczaj widziałem, jak to zrobiono, aby plik konfiguracyjny z wartościami domyślnymi był sprawdzony w repozytorium. Mogą to być na przykład wartości potrzebne na serwerze testowym. Następnie, gdy programista sprawdzi plik, będzie miał wszystkie wartości. Jeśli nowe pole zostanie dodane lub pole zostanie usunięte, zostanie to wykonane podczas scalania. Deweloper sprawdza wymaganą wartość dla serwera docelowego i nie rejestruje żadnych innych zmian w polach, które dotyczą jego osobistego środowiska programistycznego.

Dba o to, aby scalenie zostało wykonane poprawnie, ale wydaje mi się to całkiem bezpieczne.

Thomas Owens
źródło
Wydaje się to raczej podatne na błędy; Widziałem to, ale deweloperzy przypadkowo sprawdzali ustawienia osobiste, które następnie nadpisały ustawienia używane przez innych programistów :-(. Oznacza to również, że całe drzewo zawsze będzie wyświetlane jako „zmodyfikowane” w narzędziach VCS, co jest bardzo niewygodne
śleske
@sleske To wymaga pewnej dyscypliny. Ale szczerze mówiąc, spodziewałbym się, że większość programistów potrafi to zrobić dobrze.
Thomas Owens
1

Tutaj tworzymy bloki ustawień. Można to zrobić w Zend w następujący sposób:

[production]
key1: parameter1
key2: parameter2

[testing: production]
key1: parameter2
key3: parameter4

Oznacza to, że testowanie dziedziczy produkcję i rozszerza ją o klucz3. Następnie każdy programista musi ustawić swoje środowisko (w tym przypadku testowanie lub produkcja)

Agilix
źródło
Ustawienia są bardziej specyficzne dla użytkownika. Obejmują one takie elementy, jak foldery instalacyjne aplikacji, preferencje osobiste itp. Tak więc nie wystarczy wybrać tylko dwa wstępnie zdefiniowane środowisko.
Erel Segal-Halevi
W zależności od liczby ustawień i sposobu ich użycia możesz użyć zasobów w pliku ini dla Zend. Nie jestem pewien, czy dotyczy to również twojego problemu.
Agilix
Potrzebowałem bardziej ogólnego rozwiązania, które może obsłużyć wszystkie typy preferencji specyficznych dla użytkownika, a nie tylko zasoby.
Erel Segal-Halevi
Pomysł tutaj, ale czy nie lepiej byłoby przechowywać je w bazie danych? Przynajmniej preferencje. A następnie możesz powiązać tych użytkowników. Jeśli nie, to tylko myśl;)
Agilix
0

To przydatne rozwiązanie oparte na poście: Utrzymywanie haseł pod kontrolą źródła

Podsumowując, strategia polega na „zachowaniu zaszyfrowanej wersji pliku konfiguracyjnego pod kontrolą źródła, a następnie zapewnieniu środków, za pomocą których użytkownik może zaszyfrować i odszyfrować te dane”.

  1. Utwórz fikcyjny plik comfig i .gitignore go.
  2. Utwórz plik makefile, który może szyfrować i deszyfrować plik konfiguracyjny
  3. Przechowuj plik makefile i zaszyfrowany plik konfiguracyjny w repozytorium
  4. Makefile prosi o hasło i jak skontaktować się z autorem w celu uzyskania hasła.
  5. Jeśli podczas tworzenia projektu plik makefile nie został uruchomiony, powiadom użytkownika o pliku console.error („Brak pliku konfiguracyjnego [conf / settings.json]! Czy zapomniałeś uruchomić make decrypt_conf?”);
  6. Opisano sprawdzenie, aby upewnić się, że plik konfiguracyjny jest aktualny.
Głuchy
źródło
1
-1, ponieważ w ogóle nie odpowiada to oryginalne pytanie. Również odpowiedzi, które są niewiele więcej niż linkiem i nie zawierają wyjaśnień, nie są przydatne w formacie Q / A stosu wymiany, ponieważ linki zewnętrzne mogą w pewnym momencie zniknąć, nie pozostawiając odniesienia do sugerowanej odpowiedzi.
Derek
1
To jest jednak interesujący post.
Erel Segal-Halevi
0

Zbudowaliśmy narzędzie o nazwie Config, które obsługuje takie problemy z konfiguracją. Co musisz zrobić, to utworzyć (lub zaimportować) 1 główny plik konfiguracyjny. Następnie utwórz środowisko o nazwie Lokalne. W środowisku lokalnym utwórz wiele wystąpień, 1 wystąpienie na użytkownika. Jeśli chcesz dokonać zmiany, która jest wspólna na całym forum, jak dodanie nowego wpisu konfiguracji lub zmiana nazwy modułu, po prostu dokonaj zmiany, a zostanie ona zastosowana na całym forum. Jeśli chcesz dokonać zmiany instancji / użytkownika, ustaw wartość tej konfiguracji jako zmienną, a następnie zmień zmienną. Ta zmiana zostanie zastosowana tylko do Twojego wystąpienia / użytkownika. Wszystkie są pod kontrolą wersji. Wdrażasz pliki konfiguracyjne za pomocą push lub pull. Opcja pull jest podobna do git pull, ale dla tej konkretnej instancji / użytkownika.

Config zapewnia dodatkowe funkcje, takie jak porównywanie konfiguracji między użytkownikami, wyszukiwanie, oznaczanie, sprawdzanie poprawności i przepływ pracy. Jest to SaaS, więc tak naprawdę nie dla tych, którzy nie są jeszcze gotowi na chmurę, ale mamy plan lokalny.

Bienvenido David
źródło
Myślę, że włączenie SaaS do zarządzania konfiguracją programistów byłoby przesadą ... Ale to tylko moja opinia. Ponadto, jeśli konfiguracja zawiera poufne dane (mało prawdopodobne, ponieważ prawdopodobnie dotyczy to testowania na własnych stacjach roboczych), jest to natychmiastowe wyjście.
Mael
Nie sądzę, aby Config był przesadą, jeśli weźmiesz pod uwagę łatwość konfiguracji w porównaniu do czasu spędzonego na szukaniu rozwiązania, pytaniu społeczności, wdrażaniu i utrzymywaniu go. Konfiguracja działa na dowolnej platformie, formacie, języku, bibliotece, więc uczysz się tylko raz. W przypadku danych wrażliwych istnieje opcja szyfrowania po stronie klienta, jeśli to możliwe, skarbiec lokalny. Użytkownicy, którzy wezmą udział, mogą zainstalować wewnętrznie lub korzystać z VPC.
Bienvenido David