본문으로 건너뛰기

앞으로 할 것

문서 목록으로


남은 일과 하지 않기로 한 것입니다. 후자에는 이유를 적어둡니다 — 이유 없이 비어 있는 항목은 다음 사람이 같은 판단을 다시 해야 합니다.

남은 것은 7가지입니다. 그중 schema.* 메시지의 일본어·중국어가 앞섭니다 — 타입 공유가 움직일 id를 기다리고 있었고, 그것이 끝났기 때문입니다. 끝난 것은 지난 작업에 접어 두었습니다.

남은 일

무엇한 줄
schema.* 메시지의 일본어·중국어영어·한국어는 있고 나머지는 영어로 떨어집니다
uniqueBy코드 문제가 아니라 먼저 정할 것이 있습니다
깊은 스큐를 나머지 언어로건너뛰기는 전부 됐고, 넷이 아직 C#만입니다
주 레이아웃의 매트릭스 표적는 쪽은 :matrix 로 닫혔고, 이미 격자로 적힌 시트를 받는 쪽이 남았습니다
멀티 로우 그룹의 연장 행결함입니다. 원인을 좁혀 두었습니다
참조 배열의 원소 옵셔널비트맵을 읽고 버립니다. 셋 중 무엇인지 정해야 합니다
범용 압축 레이어flags bit1이 비어 있습니다. 판단을 미뤄 둡니다

schema.* 메시지의 일본어·중국어

영어와 한국어는 있고 나머지는 영어로 떨어집니다. set·map이 id를 더 얹은 것도, 타입 공유가 id를 움직인 것도 끝났으므로, 기다릴 것이 남아 있지 않습니다 (설계).

uniqueBy

담지 못하였고 코드 문제가 아닙니다.

설계 §6.5가 「유일성은 타입이 아니라 사용처에 있다」고 결론지었는데, 이 도구에서 struct 배열의 사용처는 시트의 컬럼 그룹이고 거기에는 괄호가 없습니다. 시트에 제약을 적는 자리를 늘리거나 §6.5를 뒤집거나, 둘 중 하나를 먼저 정해야 합니다.

깊은 스큐를 나머지 언어로

모르는 컬럼 건너뛰기는 전부 확인했습니다 — 적합성 드라이버를 컬럼이 하나 더 붙은 세대의 데이터로 돌립니다(conformance-skew).

남은 것은 삭제·이름 변경·타입 승격·거부이고, 그것들은 아직 C#만입니다. 그 넷은 픽스처가 세대 둘을 들어야 해서 드라이버를 언어마다 새로 써야 합니다.

주 레이아웃의 매트릭스 표

격자를 적는 쪽은 닫혔습니다:matrix 선언이 주 레이아웃에 있고, 모든 언어가 접근자를 냅니다.

남은 것은 판독 규칙 쪽입니다. 설계의 「이름이 정수인 컬럼」 규칙은 여전히 이름 기반 레이아웃에만 있고, 이미 격자로 적혀 있는 시트를 주 레이아웃에서 받으면 「컬럼 이름이 식별자가 아니다」로 막힙니다. 새로 적는 시트에는 선언이 있으므로, 이것은 옮겨 오는 시트만의 문제입니다.

멀티 로우 그룹의 연장 행

결함입니다. 원소 수가 행마다 다른 멀티 로우 그룹을 선언이 타입을 주는 컬럼과 함께 쓰면, 없는 원소의 빈 칸이 Int32 파싱 실패로 걸립니다. 같은 데이터를 시트가 직접 타이핑하면 통과하므로 두 경로 중 한쪽이 틀린 것입니다.

좁혀 둔 것: 필수 여부가 원인이 아니고(int?로 해도 같습니다), SchemaFieldTypes.Convert의 파싱도 아닙니다 — 보고되는 자리가 합성된 원소가 아니라 마지막 데이터 행이어서 위치가 오해를 부릅니다. 유력한 후보는 원소 0에서 타입을 물려받은 컬럼이 waiting이 아니게 되어 Apply가 요구 여부도 변환도 건너뛰는 것입니다. declared 쌍의 게이트를 만들다 부딪혀 원소 수를 맞춰 피해 두었습니다.

참조 배열의 원소 옵셔널

생성된 C++에서 참조 배열은 원소 비트맵을 읽기만 하고 적용하지 않습니다. 읽는 것은 블록을 지나가기 위해 필요하고, 적힌 내용은 쓰지 않습니다.

리눅스에서 CI 가 처음 돌아간 날 GCC 의 -Wunused-but-set-variable 이 드러냈습니다 — 비트맵을 걷는 커서가 한 번도 증가하지 않고 있었습니다. 커서를 그 형태에서 내지 않게 고쳤으므로 컴파일은 통과하고 값도 그대로이지만, 그 형태에 원소 옵셔널이 있어도 되는지가 열려 있습니다 (설계).

적합성 코퍼스에 그 조합이 없어서 리더 대조가 답을 주지 못합니다. 코퍼스를 넓히는 것이 먼저입니다.

범용 압축 레이어(zstd 등)

flags bit1이 비어 있습니다. 계측이 낸 숫자는 가볍지 않습니다 — 이전 대규모 코퍼스에서는 인코딩 뒤에도 Deflate가 35.8%를 더 줄입니다.

다만 그것은 모든 런타임에 압축 해제기를 들이는 값이고, 컬럼 인코딩만으로 gzip한 JSON보다 작아진 데다 v104가 같은 파일을 이미 35.5%로 만든 뒤라, 그 판단은 이 뒤에 남는 것을 보고 합니다.

하지 않기로 함

TypeScript 외의 언어에 JSON 읽기. 바이너리가 런타임 형식이고 JSON은 산출물입니다. 되읽으려면 .NET의 datetime·timespan·uuid 텍스트 형식을 언어마다 손으로 파싱해 바이너리 경로와 같은 값에 도달해야 하는데, 어긋나면 실패하지 않고 값이 달라집니다. 사람이 보는 용도는 Html 타깃이, 변경 추적은 히스토리가 대신합니다. 특정 언어에서 필요해지면 그 언어에만 코퍼스 게이트와 함께 넣습니다 (근거).

타깃을 외부 어셈블리에서 로드하는 플러그인 구조. 버전 간 안정적인 계약을 유지해야 하는데, 타깃이 전부 이 저장소 안에 있는 도구에는 값이 없습니다. 타깃 등록은 실행 어셈블리 스캔으로 합니다.

히스토리 백필. 기능이 생기기 전 커밋들은 채우지 않습니다 — 그 구간의 변경은 다음 스냅샷에 뭉치고, 뭉쳤다는 사실은 리포트에 표시됩니다.

지난 작업

기능 — 무엇이 되었고 근거가 어디 있나
무엇
중첩 필드SerialField의 원소 타입을 스칼라에서 레코드로. 모든 언어와 json·binary (설계)
멤버가 배열인 레코드형식 무변경 — 와이어가 이미 싣고 있던 형태였습니다 (설계)
배열의 배열위와 같은 형태여서 비트 하나로 끝났습니다 (설계)
다중 중첩깊이 3을 지원한 것이 아니라 깊이를 세지 않게 했습니다 (근거)
가변 길이 배열TrimTrailingArrayElements. 레코드 배열과 스칼라 배열 둘 다, 형식 무변경 (설계)
배열 가운데 빈칸거부가 기본이고 AllowArrayGaps가 되돌립니다 (설계)
옵셔널 필드 2단계와이어 비트 6 + presence 비트맵 + v103. 모든 언어와 json·binary (설계)
레코드 멤버별 옵셔널형식 무변경 — 제약은 무엇이 참이어야 하는지를 규정하지 무엇이 표현 가능해야 하는지를 규정하지 않습니다 (설계)
text 타입로컬라이즈 대상 문자열과 그 수집. 생성기도 와이어도 무변경 (타입 · 내보내기)
asset 타입파일이 있어야 하는 문자열. 없는 파일은 경고이고 어느 셀인지 함께 보고합니다 (설계)
bitset 타입최대 64개의 플래그. 파일에는 64비트 정수라 형식·리더 무변경 (설계)
합성 값 타입벡터·회전·색을 셀 하나에. 접힌 결과가 이미 지원되던 레코드라 형식·리더·생성기 무변경 (설계)
매트릭스 테이블컬럼 이름이 행 id인 표. 값은 배열 하나, 컬럼 id는 별도 테이블로. 코어 무변경 (설계)
:matrix 선언격자를 선언으로 적는 표기. 선언 하나가 테이블 둘이 되고 형식·런타임·익스포터 무변경, 축의 키는 정수가 아니어도 됩니다 (검토 · 표기)
컬럼 제약을 정적 검증으로필수값 · 최소/최대 · 값 화이트리스트. 어느 셀인지 함께 보고합니다 (설계)
멀티 로우 그룹의 선언 타입문서에 적혀 있던 표기가 받아들여지지 않고 있었습니다 (§4.3)
지역 변종테이블의 행 벌로 — 한 테이블이 데이터를 여러 벌 가지는 것이지 테이블이 둘인 것이 아닙니다
레코드 안의 참조모든 언어, 형식 무변경. 거부가 진단이 아니라 throw여서 변환이 통째로 멈췄던 것을 함께 고쳤습니다 (설계와 결과)
참조의 「없음」전에도 거부됐지만 자리가 값 파서라 메시지가 「Int32로 파싱할 수 없습니다」였습니다 (설계)
foreign[]한 셀에 구분자로 이어 적으면 원소마다 행 하나로. 생성기는 한 줄도 안 바뀌었습니다 (설계 §4)
다중 대상 참조되돌렸습니다 — 셀렉터는 공통 분모가 없어 돌려줄 타입이 없습니다. 대신 대상별 접근자·판별자·대상 무관 슬롯 셋을 냅니다 (설계)
STRUCT DSL의 set·mapset<T>·map<K,V>. 형식 무변경 — set은 배열 컬럼 하나, map은 길이가 같은 둘입니다. 모든 언어에 배열과 조회 두 겹으로. 조회를 순회한 순서는 보장하지 않고 배열이 정합니다 (설계 · 쓰는 법)
STRUCT DSL 1~5단계임베딩 오브젝트와 enum을 시트 밖 .tbs에서 선언. 형식 무변경 (설계)
struct 다형성abstract struct·extends·$type. 형식 무변경 — v103이 이미 실을 수 있던 형태였습니다 (설계)
값 임베딩 다형의 와이어 측정형식 개정이 필요 없습니다. 변종 개수보다 행의 순서가 크게 작용해, 다형 그룹을 가진 테이블은 판별자로 정렬합니다 (실측)
선언된 그룹의 타입 공유두 테이블이 같은 .tbs struct으로 타이핑한 그룹이 같은 타입이 됩니다. 이름만 바꾸면 파일 범위에 같은 이름이 두 번 나오므로, 타입 자체가 한 곳에서만 나옵니다. 형식 무변경 (설계)
행 태그와 메타 태그마커 열의 낱말이 그 행의 태그가 되고, 레시피의 ExcludeTags가 부르면 그 행이 빠집니다. 빠진 행은 시트에 없던 행이라 그 아래는 특별 처리가 없습니다. 선언과 컬럼의 tag=는 담기까지 (설계)
배열 상수표기는 받아들여지고 있었는데 어느 생성기도 내지 못했습니다 (표기)
비트폭 패킹 (v105)인코딩 13 BITPACK과 presence 비트맵의 인코딩, 모든 런타임 (설계)
동적 배열 단일화 (v107)배열은 한 종류가 되었고 길이는 언제나 로우가 정합니다 (설계)
.tcb v104컬럼 인코딩 9종 → 13종, 파일 암호화(ChaCha20). 크기는 벤치마크에 (설계)
변조 검출(MAC)과 파일 시그니처모든 런타임과 게이트도 전부. 버전은 105 그대로입니다 (설계)
큰 워크북의 메모리객체 모델을 걷어내고 스트리밍으로. peak이 GB 대에서 2,757 MB로 (설계와 실측)
.xlsb의 정의된 이름BrtName을 XTI 테이블로 풀어 읽어 사전 변환 단계를 없앴습니다 (설계)
Lua 언어 지원LuaJIT 2.1과 Lua 5.3+. 형식 무변경 (설계 · 가이드)
메시지 ID로그·에러의 로컬라이즈 앞단계. 「도구 자신의 결함」이 TabbitDefectException으로 갈라졌습니다 (설계)
검사와 보고가 가리키는 곳Naming 검사가 도구가 만든 이름을 판정하고 있었습니다. 순서가 뒤바뀐 거부도 함께
검증 파이프라인시트에 적을 수 없는 규칙을 프로젝트의 .cs로. 게이트가 모든 타깃보다 앞입니다 (사용법 · 설계)
검증의 사용성과 어셈블리 출력빌드 경고 0 · 접근자 인스턴스 · 규칙 전용 어셈블리 · 자립 배포본 · .dll 출력 · clone 직후 자동 완성 (설계)
규칙 우선순위 · 파일 명명 · 폴더 템플릿[RulePriority(n)]로 티어를 나누고, 건너뛴 규칙이 보고에 남습니다 (설계)
생성 코드의 이름 체계 통일AccessorName이 모든 언어에서 접근자 타입 이름을 정합니다. 전에는 몇몇에서만 그랬습니다 (설계)
유니티 코드의 분리엔진을 아는 파일이 tabbit/TabbitUnityAdapter.cs 하나가 되고 나머지는 평범한 netstandard입니다
이름 기반 레이아웃 파서워크북 정의된 이름을 테이블 경계로. 파서가 거부하는 테이블 0개
테스트 스위트 병렬화1,829개가 15분 53초에서 9분 08초로. 남아 있던 것은 경합 목록이 아니라 성질이었습니다 — 빌드 디렉터리가 시나리오 이름을 쓰는데 시나리오는 어느 클래스의 것도 아닙니다 (RepoLayout.WorkDir)
그 앞의 것들
  • 시트 레이아웃 파서 레이어. 임포터는 셀 격자만 만들고 그 아래는 Model 만 보므로, 레이아웃은 정확히 그 사이 한 단계입니다. 값·타입·이름 규칙을 CookingContext 로 빼서 두 파서가 「이 값이 무엇인가」에 대해 다른 결과를 낼 수 없게 했습니다. 레이아웃은 소스 항목마다 지정하므로 한 번에 섞어 읽을 수 있습니다
  • 템플릿 반복 한도가 데이터 크기의 상한이었던 문제. LoopLimit 이 100,000이었는데 행을 도는 템플릿은 행마다 1회이므로, 실제로는 「프로젝트가 가질 수 있는 행 수」의 상한이었습니다. 나온 것은 줄 번호가 찍힌 템플릿 오류라 이 저장소의 버그처럼 읽혔습니다
  • 생성 폴더 구조 통일. 런타임은 모든 언어 tabbit/ 아래이고, 타입 파일은 tables/ ·enums/·constants/로 나눕니다. 평평한 채로 둔 넷은 이유가 하나입니다 — 그 언어에선 디렉터리가 곧 패키지/모듈입니다. 선행 조건이던 마커 문제도 함께 고쳤습니다 — 런타임 파일에 배너가 없어 sweep이 지우지 못하였고, 그래서 이름이나 위치를 바꾸면 옆 이름이 소비자 프로젝트에 영원히 남았습니다
  • 레코드 조회 API 통일 — 모든 언어. 인덱싱된 필드마다 FindBy<Field> · GetBy<Field>OrThrow · Contains<Field> . 이전에는 둘만 그랬고 나머지는 기본 인덱스뿐이라 보조 인덱스가 아예 닿지 않았습니다 (가이드)
  • 데이터 갱신기 — 모든 언어. 매니페스트 비교, 해시 검증, 스테이징 후 원자적 교체, 백오프 재시도. 언어마다 없는 것(MD5·JSON 파서)을 그 파일 안에서 채웠고, 외부 의존은 세 언어뿐이며 모두 명시되어 있습니다
  • TypeScript 참조 연결. solveCrossReferences빈 메서드로 생성되고 있었습니다. 왕복 테스트가 테이블을 하나씩 읽고 원시 키만 비교해서 잡히지 않았습니다
  • 적합성 코퍼스 — 전 언어 테이블 리더를 실제로 컴파일·실행해 익스포터 JSON과 대조
  • UBT 게이트 — 생성된 언리얼 코드를 실제 엔진의 UnrealBuildTool로 빌드·실행
  • 바이너리 형식 개편 — 컬럼 지향·태그로 스키마 진화 (문서), 테이블 리더 전면 재작성, 스큐 코퍼스, 형식 바이트 고정
  • Summary 문서 및 변경 히스토리 (MySQL, 조회 CLI, 웹서버)
  • 템플릿 엔진(Scriban) 전면 도입, 직접 만든 printer 제거
  • 타깃/소스 등록을 어트리뷰트 스캔으로 전환
  • MySQL / PostgreSQL / MongoDB / Redis 적재
  • 참조 기능 강화 및 필드 참조 · 다중 오류 보고 · 상수 테이블 코드 생성
  • 배열 타입 · manifest 파일 · 키 컬럼 유니크 검사 · 주석 처리된 필드 · --target-side
  • 구글 시트 정의 위치를 URL로 출력 · 건너뛴 시트와 처리된 시트 확인 수단