go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

main.go (5168B)


      1 package main
      2 
      3 import (
      4 	"context"
      5 	"flag"
      6 	"fmt"
      7 	"os"
      8 	"path"
      9 	"strings"
     10 
     11 	fsdb "git.defalsify.org/vise.git/db/fs"
     12 	"git.defalsify.org/vise.git/debug"
     13 	"git.defalsify.org/vise.git/lang"
     14 	"git.defalsify.org/vise.git/logging"
     15 	"git.defalsify.org/vise.git/resource"
     16 )
     17 
     18 var (
     19 	logg = logging.NewVanilla()
     20 )
     21 
     22 type translator struct {
     23 	langs    []lang.Language
     24 	haveLang map[string]bool
     25 	ctx      context.Context
     26 	rs       *resource.PoResource
     27 	outPath  string
     28 	madePath bool
     29 }
     30 
     31 func newTranslator(ctx context.Context, defaultLanguage lang.Language, inPath string, outPath string) *translator {
     32 	tr := &translator{
     33 		langs:    []lang.Language{defaultLanguage},
     34 		haveLang: make(map[string]bool),
     35 		ctx:      ctx,
     36 		rs:       resource.NewPoResource(defaultLanguage, inPath),
     37 		outPath:  outPath,
     38 	}
     39 	tr.haveLang[defaultLanguage.Code] = true
     40 	return tr
     41 }
     42 
     43 func (tr *translator) AddLang(ln lang.Language) error {
     44 	var ok bool
     45 	_, ok = tr.haveLang[ln.Code]
     46 	if !ok {
     47 		tr.langs = append(tr.langs, ln)
     48 		tr.rs = tr.rs.WithLanguage(ln)
     49 		tr.haveLang[ln.Code] = true
     50 	}
     51 	return nil
     52 }
     53 
     54 func (tr *translator) nodeFunc(node *debug.Node) error {
     55 	sym := node.Name
     56 	for i, ln := range tr.langs {
     57 		ctx := context.WithValue(tr.ctx, "Language", ln)
     58 		s, err := tr.rs.GetTemplate(ctx, sym)
     59 		if err != nil {
     60 			logg.DebugCtxf(ctx, "template not found", "sym", s)
     61 			continue
     62 		}
     63 		if s != sym {
     64 			if !tr.madePath {
     65 				err := os.MkdirAll(tr.outPath, 0700)
     66 				if err != nil {
     67 					return err
     68 				}
     69 			}
     70 			fb := sym
     71 			if i > 0 {
     72 				fb += "_" + ln.Code
     73 			}
     74 			fp := path.Join(tr.outPath, fb)
     75 			w, err := os.OpenFile(fp, os.O_WRONLY|os.O_CREATE, 0644)
     76 			if err != nil {
     77 				return err
     78 			}
     79 			c, err := w.Write([]byte(s))
     80 			defer w.Close()
     81 			if err != nil {
     82 				return err
     83 			}
     84 			logg.DebugCtxf(ctx, "wrote node", "sym", sym, "lang", ln.Code, "bytes", c)
     85 		}
     86 	}
     87 	return nil
     88 }
     89 
     90 func (tr *translator) menuFunc(sym string) error {
     91 	for i, ln := range tr.langs {
     92 		ctx := context.WithValue(tr.ctx, "Language", ln)
     93 		s, err := tr.rs.GetMenu(ctx, sym)
     94 		if err != nil {
     95 			logg.DebugCtxf(ctx, "menu not found", "sym", s)
     96 			continue
     97 		}
     98 		if s != sym {
     99 			if !tr.madePath {
    100 				err := os.MkdirAll(tr.outPath, 0700)
    101 				if err != nil {
    102 					return err
    103 				}
    104 			}
    105 			// TODO: use menu sym generator func instead
    106 			fb := sym + "_menu"
    107 			if i > 0 {
    108 				fb += "_" + ln.Code
    109 			}
    110 			// TODO: use lang filename generator func instead
    111 			fp := path.Join(tr.outPath, fb)
    112 			w, err := os.OpenFile(fp, os.O_WRONLY|os.O_CREATE, 0644)
    113 			if err != nil {
    114 				return err
    115 			}
    116 			c, err := w.Write([]byte(s))
    117 			defer w.Close()
    118 			if err != nil {
    119 				return err
    120 			}
    121 			logg.DebugCtxf(ctx, "wrote menu", "sym", sym, "lang", ln.Code, "bytes", c)
    122 		}
    123 	}
    124 	return nil
    125 }
    126 
    127 func (tr *translator) Close() error {
    128 	return nil
    129 }
    130 
    131 type langVar struct {
    132 	v []lang.Language
    133 }
    134 
    135 func (lv *langVar) Set(s string) error {
    136 	v, err := lang.LanguageFromCode(s)
    137 	if err != nil {
    138 		return err
    139 	}
    140 	lv.v = append(lv.v, v)
    141 	return err
    142 }
    143 
    144 func (lv *langVar) String() string {
    145 	var s []string
    146 	for _, v := range lv.v {
    147 		s = append(s, v.Code)
    148 	}
    149 	return strings.Join(s, ",")
    150 }
    151 
    152 func (lv *langVar) Langs() []lang.Language {
    153 	return lv.v
    154 }
    155 
    156 func main() {
    157 	var dir string
    158 	var inDir string
    159 	var outDir string
    160 	var root string
    161 	var langs langVar
    162 	var defaultLanguage string
    163 
    164 	flag.StringVar(&dir, "d", ".", "node resource dir to read from")
    165 	flag.StringVar(&inDir, "i", "", "gettext dir")
    166 	flag.StringVar(&outDir, "o", "locale", "output directory")
    167 	flag.StringVar(&root, "root", "root", "entry point symbol")
    168 	flag.Var(&langs, "l", "process for language")
    169 	flag.StringVar(&defaultLanguage, "defaultlanguage", "eng", "default language to resolve for")
    170 	flag.Parse()
    171 
    172 	fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
    173 
    174 	err := os.MkdirAll(outDir, 0700)
    175 	if err != nil {
    176 		fmt.Fprintf(os.Stderr, "output dir create error: %v", err)
    177 		os.Exit(1)
    178 	}
    179 
    180 	ctx := context.Background()
    181 	rsStore := fsdb.NewFsDb()
    182 	err = rsStore.Connect(ctx, dir)
    183 	if err != nil {
    184 		fmt.Fprintf(os.Stderr, "resource db connect error: %v", err)
    185 		os.Exit(1)
    186 	}
    187 
    188 	rs := resource.NewDbResource(rsStore)
    189 
    190 	ln, err := lang.LanguageFromCode(defaultLanguage)
    191 	if err != nil {
    192 		fmt.Fprintf(os.Stderr, "invalid default language: %v", err)
    193 		os.Exit(1)
    194 	}
    195 	tr := newTranslator(ctx, ln, inDir, outDir)
    196 	defer tr.Close()
    197 	for _, ln := range langs.Langs() {
    198 		logg.DebugCtxf(ctx, "lang", "lang", ln)
    199 		err = tr.AddLang(ln)
    200 		if err != nil {
    201 			fmt.Fprintf(os.Stderr, "add language failed for %s: %v", ln.Code, err)
    202 			os.Exit(1)
    203 		}
    204 	}
    205 
    206 	nm := debug.NewNodeMap(root)
    207 	err = nm.Run(ctx, rs)
    208 	if err != nil {
    209 		fmt.Fprintf(os.Stderr, "node tree process fail: %v", err)
    210 		os.Exit(1)
    211 	}
    212 
    213 	for k, v := range debug.NodeIndex {
    214 		logg.Tracef("processing node", "sym", k)
    215 		err = tr.nodeFunc(&v)
    216 		if err != nil {
    217 			fmt.Fprintf(os.Stderr, "translate process error for node %s: %v", k, err)
    218 			os.Exit(1)
    219 		}
    220 	}
    221 
    222 	for k, _ := range debug.MenuIndex {
    223 		logg.Tracef("processing menu", "sym", k)
    224 		err = tr.menuFunc(k)
    225 		if err != nil {
    226 			fmt.Fprintf(os.Stderr, "translate process error for menu %s: %v", k, err)
    227 			os.Exit(1)
    228 		}
    229 	}
    230 
    231 }