Fix generator rebuild and release pipeline
This commit is contained in:
@@ -24,6 +24,25 @@ cd resource-generator && go build -o ../bin/resource-generator .
|
||||
|
||||
Структура: `main.go` + `internal/{helpers,loader,params,templates,types,writers}`.
|
||||
|
||||
### Как запускать правильно
|
||||
|
||||
Не запускайте `TOOLS/resource-generator/bin/resource-generator` вручную и не полагайтесь на старый бинарник из `TOOLS/resource-generator/bin/`.
|
||||
|
||||
Используйте канонический скрипт из корня репозитория, он **всегда** пересобирает генераторы из текущих исходников перед запуском:
|
||||
|
||||
```bash
|
||||
./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/dev
|
||||
```
|
||||
|
||||
Для других стендов подставляйте нужный профиль:
|
||||
|
||||
```bash
|
||||
./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/test
|
||||
./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/prod
|
||||
```
|
||||
|
||||
Это устраняет случайный запуск устаревшего бинаря и гарантирует, что новые `kind` из YAML, включая `modifier`, будут обработаны текущим кодом генератора.
|
||||
|
||||
## docs-generator
|
||||
|
||||
`resources_yaml/*.yaml` → Markdown-документация в `docs/30_registry/resources/`
|
||||
|
||||
Binary file not shown.
@@ -133,7 +133,10 @@ func LoadSpecs(dir string) ([]types.GenResource, []types.GenSubresource, []types
|
||||
gr.NeedsFmtImport = true
|
||||
}
|
||||
gr.NeedsJsonPlanMod = params.AnalyzeJsonPlanMod(gr.SchemaParams)
|
||||
gr.NeedsStringsImport = params.HasRestoreCasingParams(gr.SchemaParams) || params.AnalyzeNeedsStrings(gr.ModifyParams) || params.AnalyzeNeedsStrings(gr.CreateOnlyRequiredParams) || params.AnalyzeNeedsStrings(gr.CreateOnlyParams)
|
||||
// Строковый import нужен только для обычных строковых сравнений и
|
||||
// обработок в шаблоне. Старый restore-хук для refSvc больше не
|
||||
// генерируется, поэтому отдельный флаг под него не нужен.
|
||||
gr.NeedsStringsImport = params.AnalyzeNeedsStrings(gr.ModifyParams) || params.AnalyzeNeedsStrings(gr.CreateOnlyRequiredParams) || params.AnalyzeNeedsStrings(gr.CreateOnlyParams)
|
||||
gr.NeedsFmtImport = params.HasNestedParams(gr.SchemaParams)
|
||||
|
||||
// --- Action processing (ДО append, чтобы HasRedeploy попал в слайс) ---
|
||||
|
||||
@@ -222,12 +222,15 @@ func (r *{{ToCamel .Name}}Resource) ModifyPlan(ctx context.Context, req resource
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
// refSvc-поле резолвим только для API-запроса.
|
||||
// config не перезаписываем: пользовательский display name или UUID должен
|
||||
// пройти в state ровно в том виде, в котором его передал Terraform.
|
||||
resolved{{ToCamel .Code}} := config.{{ToCamel .Code}}.ValueString()
|
||||
if !config.{{ToCamel .Code}}.IsNull() && !config.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, config.{{ToCamel .Code}}.ValueString())
|
||||
var err error
|
||||
resolved{{ToCamel .Code}}, err = r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, config.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve {{ToSnake .Code}}", err.Error())
|
||||
} else if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != config.{{ToCamel .Code}}.ValueString() {
|
||||
config.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
@@ -236,9 +239,13 @@ func (r *{{ToCamel .Name}}Resource) ModifyPlan(ctx context.Context, req resource
|
||||
params := map[int]string{
|
||||
{{- range .CreateParams }}
|
||||
{{- if not (IsNested .) }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
{{.ID}}: resolved{{ToCamel .Code}},
|
||||
{{- else }}
|
||||
{{.ID}}: {{ParamFormat . (printf "config.%s" (ToCamel .Code))}},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
}
|
||||
{{- range .CreateParams }}
|
||||
{{- if (IsNested .) }}
|
||||
@@ -274,45 +281,22 @@ func (r *{{ToCamel .Name}}Resource) Create(ctx context.Context, req resource.Cre
|
||||
{{- end }}
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// ПРАВИЛО TERRAFORM (официальная документация):
|
||||
// «If an attribute value is configured, it is NEVER valid to change that
|
||||
// value in the plan.» — то есть plan ОБЯЗАН равняться config (= тому что
|
||||
// написал пользователь). Менять plan запрещено на уровне фреймворка.
|
||||
//
|
||||
// ПРОБЛЕМА: API нашего облака возвращает UUID в нижнем регистре.
|
||||
// Пользователь пишет: vapp_uid = "6214BA32-..." (верхний или смешанный).
|
||||
// После apply API вернул: "6214ba32-..." → state != plan → Terraform кричит:
|
||||
// «Provider produced inconsistent result after apply».
|
||||
//
|
||||
// РЕШЕНИЕ: корректировать STATE под PLAN, а не наоборот.
|
||||
// Шаг 1 (здесь): сохраняем оригинальное значение из plan ДО того как
|
||||
// ResolveRefSvcParamValue переведёт UUID в нижний регистр (нужен для API).
|
||||
// Шаг 2 (ниже, после RefreshResourceState): восстанавливаем оригинальный
|
||||
// регистр в state через strings.EqualFold (сравниваем без учёта регистра).
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
original{{ToCamel .Code}} := data.{{ToCamel .Code}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
// refSvc-поле резолвим только для API-запроса.
|
||||
// config не перезаписываем: пользовательский display name или UUID должен
|
||||
// пройти в state ровно в том виде, в котором его передал Terraform.
|
||||
resolved{{ToCamel .Code}} := data.{{ToCamel .Code}}.ValueString()
|
||||
if !data.{{ToCamel .Code}}.IsNull() && !data.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, data.{{ToCamel .Code}}.ValueString())
|
||||
var err error
|
||||
resolved{{ToCamel .Code}}, err = r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, data.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != data.{{ToCamel .Code}}.ValueString() {
|
||||
data.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
resourceName := data.ResourceName.ValueString()
|
||||
desiredDomain := ""
|
||||
{{- if .HasDomainParam }}
|
||||
@@ -363,7 +347,7 @@ func (r *{{ToCamel .Name}}Resource) Create(ctx context.Context, req resource.Cre
|
||||
{{- end }}
|
||||
}, []resources_core.InputField{
|
||||
{{- range .SchemaParams }}
|
||||
{{- if or (le .RefSvcId 0) (ne .RefSvcId 12) }}
|
||||
{{- if eq .RefSvcId 0 }}
|
||||
{Code: "{{.Code}}", Field: "{{ToCamel .Code}}", Type: "{{.Type}}"},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -372,34 +356,6 @@ func (r *{{ToCamel .Name}}Resource) Create(ctx context.Context, req resource.Cre
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !state.{{ToCamel .Code}}.IsNull() && !state.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, state.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve {{ToSnake .Code}}", err.Error())
|
||||
} else if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != state.{{ToCamel .Code}}.ValueString() {
|
||||
state.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
// Restore user-provided casing в state (Create).
|
||||
// EqualFold = «совпадают ли значения без учёта регистра?»
|
||||
// Если да — значит API вернул «туже» строку, только в другом регистре.
|
||||
// Заменяем state на original (то что было в plan/config пользователя).
|
||||
// Итог: plan=="6214BA32-..." и state=="6214BA32-..." → нет diff → нет taint.
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !original{{ToCamel .Code}}.IsNull() && !original{{ToCamel .Code}}.IsUnknown() && !state.{{ToCamel .Code}}.IsNull() && !state.{{ToCamel .Code}}.IsUnknown() {
|
||||
if strings.EqualFold(state.{{ToCamel .Code}}.ValueString(), original{{ToCamel .Code}}.ValueString()) {
|
||||
state.{{ToCamel .Code}} = original{{ToCamel .Code}}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
@@ -431,7 +387,7 @@ func (r *{{ToCamel .Name}}Resource) Read(ctx context.Context, req resource.ReadR
|
||||
{{- end }}
|
||||
}, []resources_core.InputField{
|
||||
{{- range .SchemaParams }}
|
||||
{{- if or (le .RefSvcId 0) (ne .RefSvcId 12) }}
|
||||
{{- if eq .RefSvcId 0 }}
|
||||
{Code: "{{.Code}}", Field: "{{ToCamel .Code}}", Type: "{{.Type}}"},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -440,34 +396,6 @@ func (r *{{ToCamel .Name}}Resource) Read(ctx context.Context, req resource.ReadR
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !newState.{{ToCamel .Code}}.IsNull() && !newState.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, newState.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve {{ToSnake .Code}}", err.Error())
|
||||
} else if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != newState.{{ToCamel .Code}}.ValueString() {
|
||||
newState.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
// Restore user-provided casing в state (Read).
|
||||
// При чтении у нас нет plan — но предыдущий state уже хранит значение
|
||||
// в регистре пользователя (после первого Create оно было восстановлено).
|
||||
// Берём prior state (переменная state) как эталон регистра.
|
||||
// Если API вернул то же UUID только строчными буквами — восстанавливаем.
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !state.{{ToCamel .Code}}.IsNull() && !state.{{ToCamel .Code}}.IsUnknown() && !newState.{{ToCamel .Code}}.IsNull() && !newState.{{ToCamel .Code}}.IsUnknown() {
|
||||
if strings.EqualFold(newState.{{ToCamel .Code}}.ValueString(), state.{{ToCamel .Code}}.ValueString()) {
|
||||
newState.{{ToCamel .Code}} = state.{{ToCamel .Code}}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &newState)...)
|
||||
}
|
||||
@@ -597,7 +525,7 @@ func (r *{{ToCamel .Name}}Resource) Update(ctx context.Context, req resource.Upd
|
||||
{{- end }}
|
||||
}, []resources_core.InputField{
|
||||
{{- range .SchemaParams }}
|
||||
{{- if or (le .RefSvcId 0) (ne .RefSvcId 12) }}
|
||||
{{- if eq .RefSvcId 0 }}
|
||||
{Code: "{{.Code}}", Field: "{{ToCamel .Code}}", Type: "{{.Type}}"},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -606,33 +534,6 @@ func (r *{{ToCamel .Name}}Resource) Update(ctx context.Context, req resource.Upd
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !state.{{ToCamel .Code}}.IsNull() && !state.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, state.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddWarning("Failed to resolve {{ToSnake .Code}}", err.Error())
|
||||
} else if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != state.{{ToCamel .Code}}.ValueString() {
|
||||
state.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
// Restore user-provided casing в state (Update).
|
||||
// После API-вызова modify state содержит значения в lower-case от API.
|
||||
// Plan == config == то что написал пользователь (регистр неизменён).
|
||||
// EqualFold: если UUID совпадает без учёта регистра — берём из plan.
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (ne .RefSvcId 12) (eq (ParamType .) "types.String") }}
|
||||
if !plan.{{ToCamel .Code}}.IsNull() && !plan.{{ToCamel .Code}}.IsUnknown() && !state.{{ToCamel .Code}}.IsNull() && !state.{{ToCamel .Code}}.IsUnknown() {
|
||||
if strings.EqualFold(state.{{ToCamel .Code}}.ValueString(), plan.{{ToCamel .Code}}.ValueString()) {
|
||||
state.{{ToCamel .Code}} = plan.{{ToCamel .Code}}
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
@@ -101,15 +101,17 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Create(ctx
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
// Подресурсный refSvc-параметр резолвим только в локальную переменную.
|
||||
// Сам plan не трогаем: UUID нужен лишь для backend-вызова, а в state
|
||||
// Terraform должен видеть исходное пользовательское значение.
|
||||
resolved{{ToCamel .Code}} := plan.{{ToCamel .Code}}.ValueString()
|
||||
if !plan.{{ToCamel .Code}}.IsNull() && !plan.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, plan.{{ToCamel .Code}}.ValueString())
|
||||
var err error
|
||||
resolved{{ToCamel .Code}}, err = r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, plan.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != plan.{{ToCamel .Code}}.ValueString() {
|
||||
plan.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -166,8 +168,12 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Create(ctx
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{
|
||||
{{- range .CreateParams }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
"{{.Code}}": resolved{{ToCamel .Code}},
|
||||
{{- else }}
|
||||
"{{.Code}}": {{ParamFormat . (printf "plan.%s" (ToCamel .Code))}},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
operationTimeout := ""
|
||||
@@ -249,15 +255,16 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Update(ctx
|
||||
{{- if .HasRefSvcParams }}
|
||||
{{- range .SchemaParams }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
// Update для подресурса следует тому же правилу, что и Create:
|
||||
// резолвим значение только в локальную переменную и не мутируем plan.
|
||||
resolved{{ToCamel .Code}} := plan.{{ToCamel .Code}}.ValueString()
|
||||
if !plan.{{ToCamel .Code}}.IsNull() && !plan.{{ToCamel .Code}}.IsUnknown() {
|
||||
resolved{{ToCamel .Code}}, err := r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, plan.{{ToCamel .Code}}.ValueString())
|
||||
var err error
|
||||
resolved{{ToCamel .Code}}, err = r.client.ResolveRefSvcParamValue(ctx, {{.RefSvcId}}, plan.{{ToCamel .Code}}.ValueString())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка клиента", err.Error())
|
||||
return
|
||||
}
|
||||
if resolved{{ToCamel .Code}} != "" && resolved{{ToCamel .Code}} != plan.{{ToCamel .Code}}.ValueString() {
|
||||
plan.{{ToCamel .Code}} = types.StringValue(resolved{{ToCamel .Code}})
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -284,8 +291,12 @@ func (r *{{ToCamel (printf "%s_%s" .ServiceName .SubName)}}Resource) Update(ctx
|
||||
|
||||
params := resources_core.CompactParams(map[string]string{
|
||||
{{- range .ModifyParams }}
|
||||
{{- if and (gt .RefSvcId 0) (eq (ParamType .) "types.String") }}
|
||||
"{{.Code}}": resolved{{ToCamel .Code}},
|
||||
{{- else }}
|
||||
"{{.Code}}": {{ParamFormat . (printf "plan.%s" (ToCamel .Code))}},
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
})
|
||||
|
||||
idParams := map[string]string{
|
||||
|
||||
@@ -3,6 +3,15 @@ set -euo pipefail
|
||||
|
||||
# Canonical resources+docs generator (template format).
|
||||
# Restores instruction-style docs structure (manual/example/params_create/params_modify/outputs/ops/params landing).
|
||||
#
|
||||
# Usage:
|
||||
# ./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/dev
|
||||
# ./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/test
|
||||
# ./TOOLS/scripts/02_generate_resources_and_docs_v2.sh --profile TOOLS/config/prod
|
||||
#
|
||||
# The script always rebuilds resource-generator and docs-generator from source
|
||||
# before running. This prevents stale binaries from hiding support for new YAML
|
||||
# kinds such as modifier.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT_DIR="${ROOT_DIR:-$(cd "${SCRIPT_DIR}/../.." && pwd)}"
|
||||
@@ -97,12 +106,12 @@ RESOURCE_GENERATOR_BIN="${ROOT_DIR}/TOOLS/bin/resource-generator"
|
||||
RESOURCE_GENERATOR_SRC="${ROOT_DIR}/TOOLS/resource-generator"
|
||||
DOCS_GENERATOR_BIN="${ROOT_DIR}/TOOLS/bin/docs-generator"
|
||||
DOCS_GENERATOR_SRC="${ROOT_DIR}/TOOLS/docs-generator"
|
||||
if [[ ! -x "$RESOURCE_GENERATOR_BIN" ]] || find "$RESOURCE_GENERATOR_SRC" -type f -newer "$RESOURCE_GENERATOR_BIN" -print -quit | grep -q .; then
|
||||
(cd "$RESOURCE_GENERATOR_SRC" && go build -o "$RESOURCE_GENERATOR_BIN" .)
|
||||
fi
|
||||
if [[ ! -x "$DOCS_GENERATOR_BIN" ]] || find "$DOCS_GENERATOR_SRC" -type f -newer "$DOCS_GENERATOR_BIN" -print -quit | grep -q .; then
|
||||
(cd "$DOCS_GENERATOR_SRC" && go build -o "$DOCS_GENERATOR_BIN" .)
|
||||
fi
|
||||
|
||||
# Всегда пересобираем генераторы из текущих исходников.
|
||||
# Это убирает зависимость от mtime и исключает запуск устаревшего бинаря,
|
||||
# который может не знать про новые kinds/spec-ветки в YAML.
|
||||
(cd "$RESOURCE_GENERATOR_SRC" && go build -o "$RESOURCE_GENERATOR_BIN" .)
|
||||
(cd "$DOCS_GENERATOR_SRC" && go build -o "$DOCS_GENERATOR_BIN" .)
|
||||
|
||||
NUBES_RESOURCES_DIR="$RESOURCES_YAML_DIR" \
|
||||
NUBES_RESOURCES_GEN_DIR="$TMP_GEN_DIR" \
|
||||
|
||||
Reference in New Issue
Block a user