Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コマンドラインオプションをパースするコードをコマンドラインオプションから生成するツールをつくった/fukuokago14_flagen

 コマンドラインオプションをパースするコードをコマンドラインオプションから生成するツールをつくった/fukuokago14_flagen

monochromegane

October 25, 2019
Tweet

More Decks by monochromegane

Other Decks in Programming

Transcript

  1. ࡾ୐༔հ / Pepabo R&D Institute, GMO Pepabo, Inc.
    2019.10.25 Fukuoka.go#14+Umeda.go
    ίϚϯυϥΠϯΦϓγϣϯΛύʔε͢
    ΔίʔυΛίϚϯυϥΠϯΦϓγϣϯ
    ͔Βੜ੒͢ΔπʔϧΛͭͬͨ͘

    View Slide

  2. 1SJODJQBMFOHJOFFS
    :VTVLF.*:",&!NPOPDISPNFHBOF
    1FQBCP3%*OTUJUVUF (.01FQBCP *OD
    IUUQTCMPHNPOPDISPNFHBOFDPN

    View Slide

  3. GopherCon 2019
    3
    :VTVLF.JZBLF 0QUJNJ[BUJPOGPS/VNCFSPGHPSPVUJOFT6TJOH'FFECBDL$POUSPM
    (PQIFS$PO.BSSJPUU.BSRVJT4BO%JFHP.BSJOB $BMJGPSOJB +VMZ

    View Slide

  4. 1. ͸͡Ίʹ
    2. ίϚϯυϥΠϯΦϓγϣϯΛύʔε͢ΔίʔυΛίϚϯ
    υϥΠϯΦϓγϣϯ͔Βੜ੒͢Δ
    3. ·ͱΊ
    4
    ໨࣍

    View Slide

  5. 1.
    ͸͡Ίʹ

    View Slide

  6. • ίϚϯυϥΠϯϓϩάϥϜͷڍಈΛ࣮ߦ࣌ʹมߋͤ͞ΔͨΊʹ֎෦͔ΒҾ਺΍
    ΦϓγϣϯΛࢦఆ͢Δ
    • ୯ͳΔจࣈྻͰ͋ΔͨΊɺίϚϯυϥΠϯϓϩάϥϜͰ͸͜ΕΒͷղੳॲཧΛ
    ߦ͍ɺ಺෦ͷม਺΁ͱ֨ೲ͢Δ
    • ࠷΋୯७ͳ΋ͷͰ͋Ε͹ɺۭന۠੾Γ (cp src dest)
    • Ґஔ͕ҙຯΛ͕࣋ͭ׳श͸͋ΕͲɺ͜ͷؔ܎ੑ͸໌֬Ͱ͸ͳ͍
    • Ґஔʹґଘ͠ͳ͍Φϓγϣϯܗࣜ (cp -r, head -n 10…)
    • ϢʔβϑϨϯυϦʔͰ͋Δ͕ղੳॲཧ͸΍΍ෳࡶʹͳΔ
    6
    ίϚϯυϥΠϯҾ਺ͱΦϓγϣϯ

    View Slide

  7. • ίϚϯυϥΠϯΦϓγϣϯͷղੳॲཧ͸ݴޠඪ४ͷ΋ͷ΍ϥΠϒϥϦ͔Βͨ͘
    ͞Μఏڙ͞Ε͍ͯΔʢflag, getopts, argparse, optparse…ʣ
    • શ෦Λ֮͑Δͷ͸೉͍͠ͷͰɺݴޠ΍ϥΠϒϥϦ͝ͱʹυΩϡϝϯτΛࢀর͠
    ͳ͕Β࣮૷͢Δ
    • Ͳ͏ͯ͠΋͕͔͔࣌ؒΔ
    • ఆܕॲཧͰ͋Δ͜ͱ͔Βɺߟ͑͏ΔύλʔϯΛهड़ͨ͠ϘΠϥʔςϯϓϨʔτ
    Λ४උ͢Δ
    • ൚༻తͳϘΠϥʔςϯϓϨʔτ͸Ͳ͏ͯ͠΋ฤूՕॴ͕ଟ͘ͳΔʢΦϓγϣ
    ϯ໊ɺม਺໊ɺσϑΥϧτ஋…ʣ
    7
    ίϚϯυϥΠϯΦϓγϣϯ

    View Slide

  8. 8
    ίϚϯυϥΠϯΦϓγϣϯղੳͷ՝୊ͷ੔ཧ
    $ mycli --dist erlang -e k/l --lambda 1.5 -k 1 -v
    1. ίϚϯυϥΠϯΦϓγϣϯͷܗࣜΛݕ౼͢Δ
    2. ࣮૷͢Δ
    1. υΩϡϝϯτͷࢀরͱ࣮૷
    2. ϘΠϥʔςϯϓϨʔτͷίϐʔͱฤू
    3. ຊདྷͷॲཧͷ࣮૷

    View Slide

  9. 9
    ίϚϯυϥΠϯΦϓγϣϯղੳͷ՝୊ͷ੔ཧ
    $ mycli --dist erlang -e k/l --lambda 1.5 -k 1 -v
    1. ίϚϯυϥΠϯΦϓγϣϯͷܗࣜΛݕ౼͢Δ
    2. ࣮૷͢Δ
    1. υΩϡϝϯτͷࢀরͱ࣮૷
    2. ϘΠϥʔςϯϓϨʔτͷίϐʔͱฤू
    3. ຊདྷͷॲཧͷ࣮૷
    ͜͜ͷ࣌ؒΛݶΓͳ͘
    θϩʹ͚͍ۙͮͨ

    View Slide

  10. 2.
    ίϚϯυϥΠϯΦϓγϣϯΛύʔε͢ΔίʔυΛ
    ίϚϯυϥΠϯΦϓγϣϯ͔Βੜ੒͢Δ

    View Slide

  11. • A command line option parser generator (Flag-gen).
    • https://github.com/monochromegane/flagen
    • ࣮ࡍʹ࢖͏ࡍͷίϚϯυϥΠϯΦϓγϣϯ͔ΒɺʮͦͷʯίϚϯυϥΠϯΦϓ
    γϣϯΛղੳ͢ΔϘΠϥʔςϯϓϨʔτΛੜ੒͢Δ
    • ࢖͍ํΛࢥ͍ු͔΂Δͱ࣮૷͕Ͱ͖͍ͯΔʂʂ
    11
    flagen

    View Slide

  12. Usage
    $ flagen YOUR_TEMPLATE YOUR_COMMAND_LINE_OPTIONS...
    12
    • ςϯϓϨʔτͱ࣮ࡍʹ࢖͏࣌ͷίϚϯυϥΠϯΦϓγϣϯΛ౉͚ͩ͢
    • ϓϦηοτͷςϯϓϨʔτͱͯ͠ɺGoɺRubyɺPythonɺShellΛఏڙ
    • ϑΝΠϧύεΛࢦఆ͢Ε͹ಠࣗςϯϓϨʔτ΋ར༻Մೳʢޙड़ʣ

    View Slide

  13. Example of Go (preset template)
    13
    $ flagen go --dist erlang -e k/l --lambda 1.5 -k 1 -v
    var (
    dist string
    e string
    lambda float64
    k int
    v bool
    )
    func init() {
    flag.StringVar(&dist, "dist", "erlang", "usage of dist")
    flag.StringVar(&e, "e", "k/l", "usage of e")
    flag.Float64Var(&lambda, "lambda", 1.5, "usage of lambda")
    flag.IntVar(&k, "k", 1, "usage of k")
    flag.BoolVar(&v, "v", false, "usage of v")
    }
    ίϚϯυϥΠϯΦϓγϣϯ໊͔Βม਺໊Λੜ੒
    ίϚϯυϥΠϯΦϓγϣϯ஋͔ΒܕΛਪଌ
    ࣮ࡍʹ࢖༻͢ΔίϚϯυϥΠϯΦϓγϣϯ͔Β
    ίϚϯυϥΠϯͷղੳॲཧΛੜ੒

    View Slide

  14. Example of Python (preset template)
    14
    $ flagen py --dist erlang -e k/l --lambda 1.5 -k 1 -v
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--dist", default="erlang", help="Help of dist")
    parser.add_argument("-e", default="k/l", help="Help of e")
    parser.add_argument("--lambda", type=float, default=1.5, help="Help of lambda")
    parser.add_argument("-k", type=int, default=1, help="Help of k")
    parser.add_argument("-v", action="store_false", help="Help of v")
    args = parser.parse_args()
    ϋϚΓ͕ͪͳ1ZUIPOͷCPPMͷσϑΥϧτ஋ͷઃఆ΋
    ϘΠϥʔςϯϓϨʔτͳͷͰେৎ෉

    View Slide

  15. Example of Ruby (preset template)
    15
    $ flagen rb --dist erlang -e k/l --lambda 1.5 -k 1 -v
    require 'optparse'
    opts = {
    dist: 'erlang',
    e: 'k/l',
    lambda: 1.5,
    k: 1,
    v: false,
    }
    OptionParser.new do |op|
    op.on('--dist [VALUE]', 'Desc of dist') {|v| opts[:dist] = v }
    op.on('-e [VALUE]', 'Desc of e') {|v| opts[:e] = v }
    op.on('--lambda [VALUE]', 'Desc of lambda') {|v| opts[:lambda] = v.to_f }
    op.on('-k [VALUE]', 'Desc of k') {|v| opts[:k] = v.to_i }
    op.on('-v', 'Desc of v') {|v| opts[:v] = v }
    op.parse!(ARGV)
    end

    View Slide

  16. Example of Shell (preset template)
    16
    $ flagen sh --dist erlang -e k/l --lambda 1.5 -k 1 -v
    E="k/l"
    K="1"
    V="FALSE"
    while getopts e:k:v OPT
    do
    case $OPT in
    "e" ) E="$OPTARG";;
    "k" ) K="$OPTARG";;
    "v" ) V="TRUE";;
    esac
    done
    shift `expr $OPTIND - 1`
    HFUPQUT͸ҰจࣈͷҾ਺͚ͩѻ͑ΔͷͰ௕͍Φϓγϣϯ͸ແࢹ

    View Slide

  17. • ΋ͪΖΜflagen͸ಠࣗςϯϓϨʔτ΋࢖͑Δ
    • ςϯϓϨʔτ͸Goͷtext/templateΛ࢖ͬͯॲཧ
    • `.Flags`ʹΦϓγϣϯͷղੳ݁Ռ
    • NameͱValueΛ࣋ͭ
    • Value͸͞ΒʹTypeͱGetΛ࣋ͭ
    • `.Args`ʹ࢒ΓͷҾ਺
    17
    Template

    View Slide

  18. Template

    View Slide

  19. Template
    {{ range $flag := .Flags -}}
    {{ $flag.Name }}={{ $flag.Value.Get}}({{ $flag.Value.Type }})
    {{ end }}
    19
    $ flagen my.tmpl --dist erlang -e k/l --lambda 1.5 -k 1 -v
    dist=erlang(string)
    e=k/l(string)
    lambda=1.5(float)
    k=1(int)
    v=false(bool)

    View Slide

  20. Template (Functions)
    {{ range $flag := .Flags -}}
    {{ ToCamel $flag.Name }}={{ $flag.Value.Get}}
    {{ end }}
    20
    Dist=erlang
    E=k/l
    Lambda=1.5
    K=1
    V=false

    View Slide

  21. Collaboration

    View Slide

  22. • flagenΛΤσΟλͱ࿈ܞ͢Δ
    • ྫ͑͹VimͰ͸ҎԼʹΑΓɺΧʔιϧҐஔʹ݁ՌΛૠೖ͢Δ͜ͱ͕Ͱ͖Δɻ
    ʢಈతͳίʔυεχϖοτͱͯ͠ͷར༻ʣ
    22
    Collaboration
    :r!flagen YOUR_TEMPLATE YOUR_COMMAND_LINE_OPTIONS...

    View Slide

  23. • flagenΛࣗલͷϘΠϥʔςϯϓϨʔτπʔϧͱ࿈ܞ͢Δ
    • πʔϧ͕GoͰ͋Ε͹ɺflagenΛϥΠϒϥϦͱͯ͠ར༻͢Δ͜ͱ͕Ͱ͖Δ
    23
    Collaboration
    tmpl, err := flagen.NewTemplate(args[0])
    if err != nil {
    return err
    }
    return tmpl.Execute(outStream, args[1:])
    ςϯϓϨʔτΛࢦఆ
    ग़ྗઌͱ
    ίϚϯυϥΠϯΦϓγϣϯΛࢦఆ
    4FFBMTP<(PEPD> IUUQTHPEPDPSHHJUIVCDPNNPOPDISPNFHBOFqBHFO

    View Slide

  24. Workaround

    View Slide

  25. • ᐆດͳϑϥά
    • flagen͸Φϓγϣϯʹ஋͕ࢦఆ͞Ε͍ͯͳ͍ͱ͖ʹboolͩͱݟͳͨ͢Ίɺ
    boolϑϥάͰऴΘͬͯҾ਺͕͋Δ৔߹ʹ൑அ͕͔ͭͳ͍
    • ૝ఆͲ͓Γʹ͢ΔͨΊʹ͸஋ͱͯ͠true or falseΛड͚औΔ͜ͱΛ໌ࣔ͢Δ
    25
    Workarounds - Ambiguous flag
    $ flagen TEMPLATE --bool-flag arg1
    $ flagen TEMPLATE --bool-flag=false arg1

    View Slide

  26. Implementation of template

    View Slide

  27. • ExampleςετΛ༻ҙͯ͠ग़ྗ݁ՌΛςετ͢Δ΂͠
    • Godocʹྫ͕ग़ྗ͞ΕΔͷͰศར
    • ग़ྗ༗ແͷ੾Γ෼͚͸ with action͕ศར
    27
    ςϯϓϨʔτͷ࣮૷

    View Slide

  28. 3.
    ·ͱΊ

    View Slide

  29. • ༷ʑͳ࣮૷͕ఏڙ͞Ε͍ͯΔίϚϯυϥΠϯΦϓγϣϯͷղੳॲཧΛར༻ܗࣜ
    ͔Βಈతʹੜ੒͢ΔδΣωϨʔλʔͱͯ͠flagenΛͭͬͨ͘
    • ͍͔ͭ͘ͷݴޠͷςϯϓϨʔτΛ༻ҙͯ͠ΤσΟλͱ࿈ܞͤ͞Δ͜ͱͰCLI։
    ൃͷޮ཰͕վળͨ͠
    • flagenࣗମͷΦϓγϣϯͱͯ͠prefixͳͲΛఏڙ͢Ε͹ߏ଄ମͱͷ૬ੑ΋Α͘
    ͳΓͦ͏ (hoge.nameͷΑ͏ͳ࢖͍ํ)
    • ςϯϓϨʔτ௥ՃͷϓϧϦΫΤετ΍ΠγϡʔͳͲ͓଴͍ͪͯ͠·͢
    • https://github.com/monochromegane/flagen
    29
    ·ͱΊ

    View Slide

  30. View Slide