Addressing fonts-arundina Unreproducibility
มีเวลากลับมาทำงานของ Debian รอบนี้ เรื่องหนึ่งที่ทิ้งคาราคาซังไว้นานคือ ปัญหา unreproducible ของ fonts-arundina ที่สาเหตุหลักเกิดจาก timestamp ที่ Fontforge สร้าง
ความจริงปัญหานี้ควรหมดไปนานแล้ว ตั้งแต่มีข้อกำหนด SOURCE_DATE_EPOCH เพื่อให้ซอฟต์แวร์ต่างๆ ใช้ timestamp จาก changelog ล่าสุดของ distro แทนการใช้เวลาขณะ build ที่เปลี่ยนไปเรื่อยในการ build แต่ละครั้ง และ FontForge ก็ได้รับแพตช์ที่ Debian เสนอไปตั้งนานแล้วใน fontforge#2490
ก่อนหน้านี้ผมเคยตรวจสอบมารอบหนึ่งแล้ว ก็ยังไม่เจอสาเหตุของปัญหา จึงสรุปว่าจะ workaround ไปก่อนด้วยการตัด timestamp ออกเสียเลยใน 2 commit (ใช้ sed ตัดข้อมูลใน AFM และ PFB โดยตรง, ปรับวิธีการตัดข้อมูลใน PFB ซึ่งเป็น binary) โดยนอกจาก timestamp แล้ว ก็ตัดข้อมูล Creator ที่ดันไปเอาข้อมูล user ของ build process มาแปะออกด้วย เพราะมันทำให้ขึ้นอยู่กับคนที่สั่ง build deb ซึ่งจะเป็นใครก็ได้
แต่ก็ยังเหลือปัญหาข้อมูล ItalicAngle ที่อาจใช้ comma แทนจุดทศนิยมอยู่ ซึ่งเป็นพฤติกรรมที่ขึ้นกับ locale ของระบบที่ build
แต่หลังจากที่ตัดข้อมูล creation ออกไปแล้ว ก็อยากแกะรอยหาปัญหาที่แท้จริงของ FontForge อีกสักตั้ง นั่งไล่โค้ดก็เห็นใช้ค่าจาก SOURCE_DATE_EPOCH ในฟังก์ชัน GetTime() ที่ใช้อยู่ทั่วทั้งแอปอยู่แล้ว ถ้าเช่นนั้น timestamp มันยัง vary อยู่ได้ยังไง?
รอบนี้ได้คำตอบจนได้ คือ timestamp มันเป็นสตริงที่สร้างด้วยฟังก์ชัน ctime() ของ Standard C Library ซึ่งมีการพิจารณา timezone ที่ initialize ไว้โดยฟังก์ชัน tzset() ด้วย โดยถ้าตัวแปร environment TZ มีการกำหนดค่า ก็จะมีการชดเชยนาฬิกากลับเป็น GMT ตาม timezone ที่กำหนด ซึ่งถ้าระบบที่ build เกิดมีการกำหนด TZ ขึ้นมา มันก็จะปรับค่า epoch ใน $SOURCE_DATE_EPOCH จาก timezone ใน $TZ ให้เป็น GMT แต่ปัญหาคือ epoch ใน $SOURCE_DATE_EPOCH มันเป็น GMT อยู่แล้วตั้งแต่ต้น ไปปรับซ้ำอีกมันก็เลยเพี้ยน!
กล่าวคือ โปรแกรม reprotest ได้กำหนดการกลั่นแกล้งไว้ด้วยตัวแปร environment TZ ใครไม่ระวังเรื่องนี้ก็ fail นั่นเอง
สรุปรวบยอดว่าปัญหา unreproducible ของ fonts-arundina และวิธีแก้คือ:
- timestamp ของ Creation Date เพี้ยน: แก้โดยกำหนด environment
TZ=GMT - ข้อมูล Creator ที่ไปอ่านข้อมูลจาก user ID ของโพรเซสที่ build มาแปะ: แก้โดย override environment
USER="<ชื่อผู้แก้ไขฟอนต์ล่าสุด>" - ค่า
ItalicAngleมีรูปแบบทศนิยมที่ขึ้นอยู่กับ locale: แก้โดยกำหนด locale ด้วยLC_ALL=C
ด้วยวิธีแก้ข้างต้น เราจะสามารถ revert การตัดข้อมูลการ create ฟอนต์ออก แล้วคงข้อมูลดังกล่าวแบบ reproducible ได้ แลกกับความรกรุงรังของคำสั่ง build นิดหน่อย
แต่จะคงข้อมูลการ create ไว้หรือไม่? ก็ต้องตอบคำถามว่า ข้อมูล creation date, creator มีประโยชน์อะไรไหม? มันอาจช่วยแยกแยะ version ของฟอนต์ได้? ถ้ายังมีประโยชน์ก็อาจเอากลับมา ไม่งั้นก็ตัดทิ้ง
คิดสะระตะแล้ว ข้อมูล creation date, creator อาจเคยมีประโยชน์เมื่อนักพัฒนาฟอนต์เก็บไฟล์ source ไว้กับตัว จะปล่อยฟอนต์เมื่อไรก็ generate ทำให้ข้อมูลการ create บ่งบอกการ release แต่พอเป็น open source ที่ทุกคนสามารถมี source อยู่ในมือ ผู้พัฒนากับผู้ generate ก็อาจเป็นคนละคนกัน การพยายามบอกว่าใครเป็นผู้ generate จึงไม่มีความหมายเท่าไร ในเมื่อ generate แต่ละครั้งก็มาจาก source เดิม เนื้อหาก็คงเดิม
ข้อมูลที่ควรจำแนกเนื้อหาฟอนต์ได้ดีกว่าคือฟิลด์ Version ในฟอนต์ ที่ผู้พัฒนาควรปรับค่าทุกครั้งที่ปล่อยอยู่แล้ว
สรุป: ไม่เอาข้อมูลการ create กลับมา ตัดแล้วตัดเลย ทำเพิ่มคือการบังคับ C locale เพื่อควบคุมรูปแบบจุดทศนิยม
ป้ายกำกับ: debian, fonts-arundina

0 ความเห็น:
แสดงความเห็น (มีการกลั่นกรองสำหรับ blog ที่เก่ากว่า 14 วัน)
<< กลับหน้าแรก