1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/fibjs-libgit2

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
conventions.md 17 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 21:57 67a8a28

Конвенции Libgit2

Мы стремимся поддерживать исходный код последовательным и читаемым. В данном разделе приведены некоторые руководства, которые помогут вам в этом.

Внешний API

У нас есть несколько правил, чтобы избежать неожиданных способов вызова функций и некоторых правил для потребителей библиотеки, чтобы избежать конфликтов между собой.

  • Доступ к свойствам возвращает значение напрямую (например, int или const char *), но если функция может завершиться ошибкой, мы возвращаем значение типа int, а выходные параметры располагаются первыми в списке параметров, за ними следует объект, над которым выполняется операция, и затем любые другие аргументы, необходимые данной функции.

  • Если функция возвращает объект как возвращаемое значение, эта функция является получателем, и срок службы этого объекта связан с родительским объектом. Объекты, которые возвращаются как первый аргумент в виде указателя на указатель, принадлежат вызывающему и он отвечает за его освобождение. Строки возвращаются через git_buf, чтобы обеспечить возможность повторного использования и безопасное освобождение.- Большинство действий, выполненных libgit2, связано с вводом-выводом, поэтому общее правило состоит в том, что вы должны предполагать, что любая функция может завершиться ошибкой из-за различных проблем и сложных случаев ошибок. Даже получение данных из файловой системы может привести к различным ошибкам и сложным случаям ошибок. - Пути внутри системы Git разделены слешем (0x2F). Если функция принимает путь на диске, то обратные слеши (0x5C) также принимаются на Windows.

  • Не смешивайте аллокаторы. Если что-то было распределено с помощью libgit2, вы не знаете, какой метод освобождения является правильным в общем случае. Используйте методы освобождения, предоставляемые для каждого типа объекта.

Совместимость

libgit2 работает на многих разных платформах с множеством различных компиляторов.

Открытый API libgit2 совместим с стандартом ANSI C (или C89).

Внутри libgit2 используется портабельная часть стандарта C99 — для максимизации совместимости (например, с MSVC) мы избегаем некоторых расширений C99. Конкретнее, мы сохраняем объявления локальных переменных только в начале блока и избегаем стиля комментариев //.

Кроме того, насколько это возможно, мы стараемся избегать большого количества #ifdef внутри основной базы кода. Это в некоторой степени неизбежно, но поскольку это может существенно затруднять поддержание кода, мы стараемся ограничить использование этих директив до минимума.## Соответствие окружающему коду

Если есть одна ключевая рекомендация, которую следует вынести из этого документа, это правило: новый код должен соответствовать окружающему коду так, чтобы было невозможно отличить новое от старого. Консистентность важнее личного мнения о том, где должны располагаться фигурные скобки или пробелы вместо табуляции.Если часть кода полностью перезаписывается, можно привести её в соответствие с здесь описываемыми стандартами, но мы не примем подачи, содержащие большое количество изменений, которые являются лишь реформаттированием.

Название вещей

Все внешние типы и функции начинаются с префикса git_, а все макросы #define — с префикса GIT_. API библиотеки libgit2 в основном разделён на связанные функциональные модули, каждый из которых имеет соответствующий заголовочный файл. Все функции внутри модуля должны называться как git_modulename_functionname() (например, git_repository_open()).

Функции с одним выходным параметром должны называть этот параметр out. Множественные выходные параметры должны называться foo_out, bar_out и т.д.

Параметры типа git_oid должны называться id или foo_id. Вызовы, которые возвращают OID, должны называться git_foo_id.

Когда используется обратный вызов функции, функция также должна содержать дополнительный входной параметр пользователя типа void *, который будет передан обратному вызову при каждом вызове.

Определение типов

По возможности используйте typedef. В некоторых случаях, если структура представляет собой просто коллекцию указателей на функции, эти указатели не требуют отдельного определения типа typedef, но свободные указатели на функции должны быть определены.## Экспорты

Все экспортированные функции должны объявляться следующим образом:

GIT_EXTERN(результат_тип) git_имя_модуля_функции(список_аргументов);

Внутренняя реализация

Функции, чье имя модуля заканчивается двумя подчеркиваниями (например, git_odb__read_packed), являются полу-непубличными функциями. Они предназначены главным образом для использования внутри самой библиотеки и могут исчезнуть или изменить свой прототип в будущих версиях.

Параметры

Выходные параметры располагаются первыми.

По возможности передавайте указатели аргументов как const. Некоторые структуры (например, git_repository и git_index) имеют внутреннюю структуру, которая делает невозможным использование const.

Обратные вызовы всегда должны принимать void * payload в качестве последнего параметра. Указатели обратных вызовов группируются вместе со своими payload, и обычно располагаются последними при передаче как аргументы.

int git_foo(git_repository *repo, git_foo_cb callback, void *payload);

Вопросы владения памятью

Некоторые API выделяют память, за освобождением которой отвечает вызывающая сторона; другие возвращают указатель на буфер, который принадлежит какому-то другому объекту. Укажите это явно в документации.

Коды возврата

Большинство открытых API должны возвращать целочисленный код ошибки. Как обычно с большинством функций C-библиотек, нулевое значение указывает на успешное выполнение, а отрицательное — на ошибку.Некоторые привязки преобразуют эти коды ошибок в типы исключений, поэтому важно возвращать семантически подходящий код ошибки. Проверьте include/git2/errors.h для уже определённых кодов возврата.

В вашей реализации используйте git_error_set(), чтобы предоставить расширенную информацию об ошибке вызывающей стороне.

Если внутренняя функция libgit2 вызывает другую функцию, которая сообщает об ошибке, но эта ошибка не передается выше, используйте git_error_clear(), чтобы предотвратить получение неверного сообщения об ошибке вызывающей стороной позднее.

Структуры

Большинство открытых типов должны быть прозрачными, например:

typedef struct git_odb git_odb;

...с функциями выделения памяти, которые возвращают "экземпляр", созданный внутри библиотеки, а не внутри приложения. Это позволяет типу расти (или уменьшаться) по размеру без необходимости перестроения клиентского кода.

Чтобы сохранить совместимость ABI, включите поле int version во всех прозрачных структурах, и инициализируйте его последней версией в конструкторе. Увеличивайте "последнюю" версию каждый раз, когда структура изменяется, и старайтесь добавлять новые поля только в конец структуры.

Опциональные структурыЕсли количество параметров функции слишком велико, может потребоваться упаковать опции в структуру. Сделайте их прозрачными, включите поле версии и предоставьте константу инициализатора или конструктор. Использование этих структур должно быть таким простым:```C

git_foo_options opts = GIT_FOO_OPTIONS_INIT; opts.baz = BAZ_OPTION_ONE; git_foo(&opts);


## Перечисления

Создайте typedef для всех перечисляемых типов. Если каждая опция стоит отдельно, используйте тип перечисления для передачи их как параметров; если они являются флагами, которые следует объединять операцией OR, передавайте их как `unsigned int` или `uint32_t` или какого-либо подходящего типа.

## Размещение кода

Постарайтесь сохранять строки менее 80 символов в длину. Это слабое требование, но превышение 80 столбцов — это не очень хорошо.

Используйте здравый смысл для переноса большинства строк кода; объявления публичных функций могут использовать несколько различных стилей:

```c
/** Все на одной строке допустимо, если помещается */
GIT_EXTERN(int) git_foo_simple(git_oid *id);

/** В противном случае один аргумент на каждую строку — хорошее следующее решение */
GIT_EXTERN(int) git_foo_id(
	git_oid **out,
	int a,
	int b);

Отступайте с помощью табуляций; установите ширину табуляции вашего редактора на восемь для наилучшего эффекта.

Избегайте пробелов в конце строк и только коммитьте Unix-стильные новогодние строки (то есть без CRLF в репозитории — просто установите core.autocrlf как true, если вы пишете код на машине Windows).

ДокументацияВсе комментарии должны соответствовать конвенциям форматирования публичной API-документации в стиле Doxygen "javadoc". Постарайтесь документировать каждый параметр, и поддерживайте актуальность комментариев при изменении списка параметров.## Шаблон публичного заголовка

Используйте этот шаблон при создании нового публичного заголовка.

#ifndef INCLUDE_git_${filename}_h__
#define INCLUDE_git_${filename}_h__

#include "git/common.h"

/**
 * @file git/${filename}.h
 * @brief Описание Git
 * @defgroup git_${filename} описание рутин
 * @ingroup Git
 * @{
 */
GIT_BEGIN_DECL

/* ... определения ... */

/** @} */
GIT_END_DECL
#endif

Встроенные функции

Все встроенные функции должны объявляться как:

GIT_INLINE(тип_результата) git_modulename_functionname(список_параметров);

GIT_INLINE (или inline) не следует использовать в публичных заголовках для сохранения совместимости с ANSI C.

Тесты

libgit2 использует тестовый фреймворк clar.

Все запросы на слияние (PRs) должны иметь соответствующие тесты.

  • Если запрос на слияние исправляет существующую проблему, тест должен проваливаться до применения запроса на слияние и проходить после его применения.
  • Если запрос на слияние предназначен для новых возможностей, то тесты должны проверять эти новые возможности до некоторой степени. Мы пока не требуем 100%-го покрытия (хотя мы становимся строже со временем).

Когда добавляются новые тесты, мы предпочитаем попытки переиспользования существующих данных тестов (в tests-clar/resources/) по мере возможности. Если вы собираетесь добавить новые тестовые хранилища, пожалуйста, постарайтесь удалить из них ненужные файлы (например, образцы хуков и т.д.).

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/fibjs-libgit2.git
git@api.gitlife.ru:oschina-mirror/fibjs-libgit2.git
oschina-mirror
fibjs-libgit2
fibjs-libgit2
main