authzmapgen

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package authzmapgen — ПРОИЗВОДИТЕЛЬ двух таблиц типов пакета `authzmap` из манифестов модулей (задача #1092).

───────────────────────────────────────────────────────────────────────────── ПРЕДМЕТ: СВЕРКУ ЗАМЕНЯЕТ ВЫВОД

Перечень «набор глагольных отношений каждого типа» жил в Go рукописным литералом, а манифест модуля объявлен источником истины о том, что у платформы существует. Два места об одном предмете обязаны совпадать — и совпадение стерёг гейт.

Гейт равенства и вывод решают одну задачу с разной ценой ошибки: гейт ловит расхождение ПОСЛЕ того, как оно внесено, и требует править Go при объявлении действия; вывод делает расхождение невыразимым by construction. «Объявить действие» перестаёт быть правкой Go.

───────────────────────────────────────────────────────────────────────────── КРУГ «ПРОИЗВОДИТЕЛЬ СПРАШИВАЕТ У СВОЕГО ПРОДУКТА» — РАЗОРВАН (задача #1930)

Здесь стояло: вторую таблицу каталога — `objectTypes` — вывести НЕЛЬЗЯ, потому что загрузчик проверяет `objectType` каждой записи на членство в ней же, и новый тип не проходит ни одной из двух дверей. Это было верно ровно до смены РЕФЕРЕНТА, и абзац оставлен разбором, а не удалён: следующий, кто упрётся в тот же круг, обязан найти здесь способ, а не запрет.

Что теперь верно: `Collect` зовёт `manifest.CheckTreeForGeneration`, и в этом проходе загрузчик существование типа НЕ СУДИТ — судит его канон, сверку с которым в обе стороны ведёт `modelrender.Sweep` («манифест порождает тип, которого в каноне НЕТ» и обратное). Форму — «тип назван дословно» — загрузчик судит по-прежнему и при любом референте.

Полоса ПОТРЕБЛЕНИЯ не тронута: чтение доставленных манифестов на старте службы идёт умолчанием, то есть таблицей, и там она законный судья — к тому моменту она уже произведена и вкомпилирована. Почему это ОДИН предикат с двумя законными референтами, а не два места об одном предмете — `manifest.TypeReferent`.

───────────────────────────────────────────────────────────────────────────── ГРАНИЦА, КОТОРУЮ НАДО ЗНАТЬ: ПРОИЗВОДИТЕЛЬ ЗАВИСИТ ОТ СВОЕГО ПРОДУКТА

Загрузчик манифеста импортирует `authzmap` — тот самый пакет, в который пишется продукт. Значит перегенерация возможна только из СОБИРАЮЩЕГОСЯ состояния: удали продукт — и производитель перестанет собираться вместе с ним. Штатный случай (манифест изменился, продукт устарел) от этого не страдает: устаревший продукт компилируется. Смена референта эту границу НЕ снимает: она про импорт пакета, а не про содержимое таблицы, — и это надо сказать прямо, иначе разбор выше прочтётся шире сделанного.

───────────────────────────────────────────────────────────────────────────── ПОЧЕМУ ГЕНЕРАТОР ЖИВЁТ ЗДЕСЬ, А НЕ В `tools/`

Форму манифеста судит ОДИН исполнитель — загрузчик `services/iam/internal/manifest`, — и он закрыт правилом видимости Go для пакетов вне `services/iam/`. Генератор в `tools/` пришлось бы снабдить ВТОРЫМ разбором той же формы, и разошлись бы они молча: генератор перестал бы видеть ключ, который загрузчик принимает, а таблица тихо потеряла бы тип. Тот же довод уже записан у гейта манифестов в `internal/repohygiene`, где отступление названо вместе с причиной — она свойство языка, а не выбор.

Здесь свойство языка работает В НАШУ ПОЛЬЗУ: генератор внутри `services/iam/` зовёт настоящий загрузчик, и второго объявления формы не заводится.

───────────────────────────────────────────────────────────────────────────── ПОЧЕМУ ГЕЙТ ДРЕЙФА С МОДЕЛЬЮ ОСТАЁТСЯ

Он сверяет таблицы с КАНОНИЧЕСКОЙ МОДЕЛЬЮ, а не с манифестом, и предмет у него другой: манифест и канон — два рендера одного замысла, и их согласие есть утверждение, которое кто-то обязан проверять. Снять его вместе с заведением вывода значило бы оставить дерево без обоих.

Index

Constants

View Source
const GeneratedRelPath = "services/iam/internal/authzmap/tables_gen.go"

GeneratedRelPath — координата порождённого файла от корня репозитория.

Объявлена ЗДЕСЬ и один раз: её знают команда записи и гейт свежести, и второе объявление развело бы их молча — гейт сверял бы файл, которого никто не пишет.

Variables

This section is empty.

Functions

func Render

func Render(t Tables) ([]byte, error)

Render — порождённый файл целиком, отформатированный тем же инструментом, что и остальное дерево.

Форматирование ЗДЕСЬ, а не советом читателю: файл сверяется побайтово, и расхождение отступа читалось бы как расхождение таблицы.

Types

type Census

type Census struct {
	ManifestsRead int
	PathsSeen     int
	Modules       int
	Resources     int
	VerbBearing   int
	VerbRelations int
	// InternalExcluded — действий ВНУТРЕННЕЙ плоскости, не вошедших в набор.
	//
	// В `StableSummary` (а значит и в порождённый файл) НЕ входит намеренно:
	// туда идут только величины, из которых собран сам файл, а исключённое в
	// него по построению не попало. Здесь же число несущее — без него
	// «отношений действия 109» неотличимо от «внутренних действий нет вовсе»,
	// и снятая ветвь исключения выглядела бы как исправная работа.
	InternalExcluded int
}

Census — ОБЪЁМ осмотренного. Печатается вызывающим всегда: «ноль расхождений» обязано быть отличимо от «ноль прочитанного».

func CheckFresh

func CheckFresh(root string) (Census, error)

CheckFresh — ОДИН предикат свежести на обоих вызывающих: гейт дерева и доказательство его способности упасть.

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

Отдаёт перепись ВСЕГДА, включая исход отказа: без неё «файл отстал» не отличается от «манифестов не нашлось», а чинятся эти два состояния по-разному.

func (Census) StableSummary

func (c Census) StableSummary() string

StableSummary — перепись для ПОРОЖДЁННОГО ФАЙЛА: только величины, зависящие от манифестов.

Объём обхода сюда НЕ входит намеренно. Он считает файлы всего дерева, то есть меняется от всякой правки где угодно, — и файл, несущий его, расходился бы со своим производителем на изменении, которое к таблицам отношения не имеет. Гейт свежести краснел бы, а находка называла бы не предмет: прокси-предикат, ломающийся раньше того, что он стережёт.

func (Census) Summary

func (c Census) Summary() string

Summary — перепись одной строкой, ВКЛЮЧАЯ объём обхода.

Печатается командой и гейтом: там объём обхода и есть то, что отличает «ноль находок» от «ноль прочитанного».

type Tables

type Tables struct {
	Entries []TypeEntry
	Census  Census
}

Tables — то, что генератор вывел из дерева.

func Collect

func Collect(root string) (Tables, error)

Collect читает манифесты ДЕРЕВА тем же обходом и тем же загрузчиком, каким их читает проверка дерева, и выводит обе таблицы.

Находка обхода — ОТКАЗ, а не пропуск записи: таблица, собранная из части манифестов, выглядит целой и молча теряет тип, а потерянный тип не резолвится краем — вопрос о нём не задаётся вовсе, и проверка выглядит пройденной.

Беспредметный обход — тоже отказ: «манифестов ноль» неотличимо от «манифесты прочитаны и в них ничего нет», а порождённая из пустоты таблица снесла бы каталог целиком.

func (Tables) ObjectTypeSet

func (t Tables) ObjectTypeSet() map[string]struct{}

ObjectTypeSet — множество типов модели, которые производитель эмитит.

Отдаётся ОТСЮДА, а не собирается вызывающим: второй обход тех же записей разошёлся бы с первым на первом же новом виде записи.

type TypeEntry

type TypeEntry struct {
	// Dotted — имя в словаре КАТАЛОГА: `<модуль>.<ресурс>`.
	Dotted string
	// ObjectType — имя в словаре МОДЕЛИ ПРАВ.
	ObjectType string
	// VerbRelations — набор `v_*`, объявленный этим типом, отсортированно.
	//
	// Пусто означает «тип не глагольный»: строки в `typeVerbRelations` он не
	// даёт вовсе. Различать это от «набор пуст» обязан читатель — потому и
	// отдаётся nil, а не пустой срез.
	VerbRelations []string
}

TypeEntry — одна строка обеих таблиц сразу.

Строка одна, потому что и точечное имя, и набор отношений объявляет ОДНА запись манифеста: разведя их по двум структурам, генератор завёл бы два обхода одного предмета.

type TypeTableSurvey

type TypeTableSurvey struct {
	// FilesRead — не-тестовых файлов Go прочитано.
	FilesRead int
	// MapsRead — package-level карт прочитано, включая не-типовые.
	MapsRead int
	// Generated — таблиц типов в ПОРОЖДЁННОМ файле.
	Generated int
	// HandWritten — таблиц типов вне порождённого файла.
	HandWritten int
	// HandWrittenNames — их имена, отсортированно: находка обязана называть
	// предмет, иначе читатель идёт искать его сам.
	HandWrittenNames []string
}

TypeTableSurvey — объём осмотренного и вердикт.

Печатается ВСЕГДА: «рукописных одна» неотличимо от «прочитано ноль файлов», если объём не назван.

func SurveyTypeTables

func SurveyTypeTables(dir string, types map[string]struct{}) (TypeTableSurvey, error)

SurveyTypeTables обходит каталог пакета продукта и считает таблицы типов.

Каталог подаётся ПУТЁМ, а не содержимым: инъекция подаёт синтетический тем же путём, каким гейт подаёт настоящий, поэтому доказательство способности упасть относится к ЭТОЙ функции, а не к её копии.

Пустой набор типов — ОТКАЗ, а не «таблиц ноль»: предикат «все элементы суть типы» на пустом наборе не выполняется никогда, и перепись молча объявила бы пакет свободным от таблиц.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL