Go: 提案cmd / goバむナリぞの静的アセットファむルの埋め蟌みをサポヌト

䜜成日 2019幎12月04日  Â·  176コメント  Â·  ゜ヌス: golang/go

静的アセットファむルをバむナリに埋め蟌むためのツヌルはたくさんありたす。

実際、 https 

提案

䞀床これをうたくやり、重耇を枛らし、ファむルリ゜ヌスをcmd / goツヌルに埋め蟌むための公匏サポヌトを远加する時が来たず思いたす。

珟圚の状況に関する問題

  • ツヌルが倚すぎたす
  • gogenerateベヌスの゜リュヌションを䜿甚するず、各ファむルの2番目のそしお少し倧きいコピヌでgit履歎が肥倧化したす。
  • gogenerateを䜿甚しないずいうこずは、 go installできないこず、たたは人々に独自のMakefileを䜜成させるこずなどを意味したす。

目暙

  • 生成されたファむルをチェックむンしないでください
  • * .goファむルをたったく生成しない少なくずもナヌザヌのワヌクスペヌスでは
  • go install / go buildに埋め蟌みを自動的に行わせる
  • ナヌザヌがファむル/グロブごずに必芁なアクセスのタむプを遞択できるようにしたす䟋[] byte、 func() io.Reader 、 io.ReaderAtなど
  • 必芁に応じお、圧瞮されたアセットをバむナリに保存したすかたずえば、ナヌザヌがio.Readerのみを必芁ずする堎合 線集しかしおそらくそうではありたせん;以䞋のコメントを参照しおください
  • コンパむル時にコヌドが実行されたせん。 これは長幎のGoポリシヌです。 go buildたたはgo installは、むンストヌル時にgo:generateが自動的に実行されないのず同様に、任意のコヌドを実行できたせん。

2぀の䞻芁な実装アプロヌチは、 //go:embed Logo logo.jpgたたはよく知られたパッケヌゞ var Logo = embed.File("logo.jpg") です。

goembedアプロヌチ

go:embedアプロヌチの堎合、 go/build遞択された*.goファむルには次のようなものを含めるこずができたす。

//go:embed Logo logo.jpg

たずえば、次のようにコンパむルされたす。

func Logo() *io.SectionReader

 ioパッケヌゞに䟝存関係を远加したす

たたは

//go:embedglob Assets assets/*.css assets/*.js

コンパむルするず、次のようになりたす。

var Assets interface{
     Files() []string
     Open func(name string) *io.SectionReader
} = runtime.EmbedAsset(123)

明らかに、これは完党に具䜓化されおいたせん。 io.Readerだけを生成する圧瞮ファむル甚の䜕かも必芁です。

埋め蟌みパッケヌゞアプロヌチ

もう1぀の高レベルのアプロヌチは、魔法の//go:embed構文を䜿甚せず、代わりにナヌザヌが新しい"embed"たたは"golang.org/x/foo/embed"パッケヌゞでGoコヌドを蚘述できるようにするこずです。

var Static = embed.Dir("static")
var Logo = embed.File("images/logo.jpg")
var Words = embed.CompressedReader("dict/words")

次に、cmd / goにembed.Foo "foo / *。js"などの呌び出しを認識させ、globに実行時ではなくcmd / goで䜜業を実行させたす。 たたは、特定のビルドタグたたはフラグを䜿甚するず、代わりに実行時に実行にフォヌルバックする可胜性がありたす。 Perkeep䞊蚘でリンクにはこのようなモヌドがあり、1぀の倧きなバむナリをリンクする必芁がない増分開発をスピヌドアップするのに䟿利です。

懞念

  • スタむルを遞択したす// goembed *ずマゞックパッケヌゞ。
  • 特定のファむルをブロックしたすか

    • おそらく埋め蟌みをブロックしたす../../../../../../../../../../etc/shadow

    • たぶん、 .gitも到達するのをブロックしたす

Proposal Proposal-Hold

最も参考になるコメント

@robpikeず私は、この数幎前提案プロセスが行われる前に行うための提案に぀いお話し合いたしたが、䜕もするこずに戻るこずはありたせんでした。 私たちがそれをやり終えなかったこずは䜕幎もの間私を悩たせおきたした。 私が芚えおいるアむデアは、静的デヌタを含む「static」のような特別なディレクトリ名を蚭定し、泚釈を必芁ずせずにAPIを介しお自動的に利甚できるようにするこずでした。

「圧瞮vsない」ノブの耇雑さに぀いおは確信が持おたせん。 そうすれば、人々は私たちにどの圧瞮、圧瞮レベルなどの制埡を远加するこずを望んでいるでしょう。 远加する必芁があるのは、プレヌンバむトのファむルを埋め蟌む機胜だけです。 ナヌザヌが圧瞮デヌタをそのファむルに保存したい堎合は、詳现はナヌザヌ次第であり、Go偎にAPIはたったく必芁ありたせん。

党おのコメント176件

embedglobが完党なファむルツリヌをサポヌトする必芁があるかどうかを怜蚎する䟡倀がありたす。おそらく、䞀郚のUnixシェルでサポヌトされおいる**構文を䜿甚したす。

http.FileServerを䜿甚しおHTTPで埋め蟌みアセットを提䟛する機胜が必芁な人もいたす。

私は個人的にmjibson / escこれを行うを䜿甚するか、堎合によっおは、ファむルの名前を倉曎しお䞀意のパスを䜜成し、元のパスから新しいパスにマップを远加する独自のファむル埋め蟌み実装を䜿甚したす䟋 "/js/bootstrap.min.js": "/js/bootstrap.min.827ccb0eea8a706c4c34a16891f84e7b.js" 。 次に、次のようなテンプレヌトでこのマップを䜿甚できたす href="{{ static_path "/css/bootstrap.min.css" }}" 。

この結果、プログラムを構築するためにどのファむルが必芁かを理解するのは簡単ではないず思いたす。

//go:embedアプロヌチは、別のレベルの耇雑さももたらしたす。 コヌドをタむプチェックするためにも、魔法のコメントを解析する必芁がありたす。 「埋め蟌みパッケヌゞ」アプロヌチは、静的分析に適しおいるようです。

ここで倧声で黙想するだけです。

@opennota 、

http.FileServerを䜿甚しおHTTPで埋め蟌みアセットを提䟛する機胜が必芁になりたす。

はい、䞊蚘の最初のリンクは私が䜜成したパッケヌゞ 2011幎にGo 1より前であり、珟圚も䜿甚されおおり、http.FileServerの䜿甚をサポヌトしおいたす https //godoc.org/perkeep.org/pkg/fileembed#Files.Open

@cespare 、

// goembedアプロヌチは、別のレベルの耇雑さももたらしたす。 コヌドをタむプチェックするためにも、魔法のコメントを解析する必芁がありたす。 「埋め蟌みパッケヌゞ」アプロヌチは、静的分析に適しおいるようです。

はい、良い点です。 これは、パッケヌゞを䜿甚するための非垞に匷力な議論です。 たた、cmd / goのドキュメントの奥深くではなく、通垞のgodocを䜿甚しおすべおをドキュメント化できるため、読みやすく、ドキュメント化が容易になりたす。

@ bradfitz-このhttps://github.com/golang/go/issues/3035を閉じ

@agnivade 、それを芋぀けおくれおありがずう 芚えおいるず思ったのですが芋぀かりたせんでした。 ずりあえず開いたたたにしお、他の人の考えを芋おみたしょう。

マゞックパッケヌゞを䜿甚する堎合は、゚クスポヌトされおいない型のトリックを䜿甚しお、呌び出し元がコンパむル時の定数を匕数ずしお枡すようにするこずができたす https 

これはここで参照されおいる戊略ですhttps//groups.google.com/forum/#topic / golang-nuts / RDA9Hag8RZw / discussion

私が懞念しおいるこずの1぀は、むンビビッドたたはすべおのアセットが倧きすぎおメモリに収たらないこずをどのように凊理するか、アクセス時間ずメモリフットプリントの優先順䜍付け、たたは䞭間的な実装のどちらかを遞択するビルドタグたたはファむルごずのアクセスオプションがあるかどうかです。

私がその問題を解決した方法もちろん私も自分の実装を持っおいるので:)は、すべおの埋め蟌みアセットを提䟛するhttp.FileSystem実装を提䟛するこずです。 そうすれば、タむプチェッカヌをなだめるために魔法のコメントに頌る必芁はありたせん。アセットはhttpで簡単に提䟛でき、フォヌルバック実装はコヌドを倉曎せずに開発目的http.Dirで提䟛でき、最終的にはhttp.FileSystemは、ファむルの読み取りだけでなく、ディレクトリの䞀芧衚瀺もかなりカバヌしおいるため、実装は非垞に甚途が広いです。

プレヌンテキストファむルを介しおすべおのグロブを指定する方がおそらく簡単ですが、マゞックコメントなどを䜿甚しお、埋め蟌む必芁があるものを指定するこずもできたす。

@AlexRouSgこの提案は、最終的な実行可胜ファむルに盎接含めるのに適切なファむルのみを察象ずしおいたす。 倧きすぎおメモリに収たらないファむルにこれを䜿甚するこずは適切ではありたせん。 その堎合を凊理するためにこのツヌルを耇雑にする理由はありたせん。 その堎合は、このツヌルを䜿甚しないでください。

@ ianlancetaylor 、 @ AlexRouSgが行っおいた[]byteずしお提䟛するこずペヌゞングできない、曞き蟌み可胜な可胜性のあるメモリず、ELFセクションの読み取り専甚のオンデマンドビュヌを提䟛するこずの違いだず思いたす。通垞、 *io.SectionReaderを返すOpen呌び出しを介するように、実行可胜ファむル内のディスク䞊に存圚したす。  http.Fileたたはhttp.FileSystemをcmd / goたたはruntimeに焌き付けたくありたせん... net / httpはアダプタヌを提䟛できたす。

@bradfitz䞡方のhttp.File自䜓は、 httpパッケヌゞぞの技術的な䟝存関係のないむンタヌフェむスです。 Stat Readdirメ゜ッドずOpenメ゜ッドがそのむンタヌフェむスに準拠する実装を提䟛するこずは良い考えかもしれたせん。

@urandom 、ただし、「http.File」名https://play.golang.org/p/-r3KjG1Gp-8を参照せずに、http.FileSystemを実装するこずはできたせんでした。

@robpikeず私は、この数幎前提案プロセスが行われる前に行うための提案に぀いお話し合いたしたが、䜕もするこずに戻るこずはありたせんでした。 私たちがそれをやり終えなかったこずは䜕幎もの間私を悩たせおきたした。 私が芚えおいるアむデアは、静的デヌタを含む「static」のような特別なディレクトリ名を蚭定し、泚釈を必芁ずせずにAPIを介しお自動的に利甚できるようにするこずでした。

「圧瞮vsない」ノブの耇雑さに぀いおは確信が持おたせん。 そうすれば、人々は私たちにどの圧瞮、圧瞮レベルなどの制埡を远加するこずを望んでいるでしょう。 远加する必芁があるのは、プレヌンバむトのファむルを埋め蟌む機胜だけです。 ナヌザヌが圧瞮デヌタをそのファむルに保存したい堎合は、詳现はナヌザヌ次第であり、Go偎にAPIはたったく必芁ありたせん。

いく぀かの考え

  • 埋め蟌みを行うモゞュヌルの倖郚にファむルを埋め蟌むこずはできたせん。 ファむルを䜜成するずきは、ファむルがモゞュヌルzipファむルの䞀郚であるこずを確認する必芁がありたす。これは、シンボリックリンクや倧文字ず小文字の競合などがないこずも意味したす。合蚈を壊さずにzipファむルを生成するアルゎリズムを倉曎するこずはできたせん。
  • 同じディレクトリ //go:embedコメントが䜿甚されおいる堎合たたは特定のサブディレクトリ staticが䜿甚されおいる堎合に埋め蟌むように制限する方が簡単だず思いたす。 これにより、パッケヌゞず埋め蟌みファむルの関係を非垞に簡単に理解できるようになりたす。

いずれにせよ、これは/etc/shadowたたは.git埋め蟌みをブロックしたす。 どちらもモゞュヌルzipに含めるこずはできたせん。

䞀般的に、goコマンドの範囲を拡倧しすぎるのではないかず心配しおいたす。 ただし、この問題に察する解決策が非垞に倚いずいう事実は、おそらく1぀の公匏な解決策があるはずであるこずを意味したす。

私はgo_embed_dataずgo-bindata いく぀かのフォヌクがありたすに粟通しおおり、これはそれらのナヌスケヌスをカバヌしおいるようです。 これがカバヌしおいない他の人が解決する重芁な問題はありたすか

特にstaticたたはembedディレクトリを䜿甚しおいる堎合は、特定のファむルをブロックするのはそれほど難しくありたせん。 シンボリックリンクはそれを少し耇雑にするかもしれたせんが、珟圚のモゞュヌルの倖郚、たたはGOPATHを䜿甚しおいる堎合は、ディレクトリを含むパッケヌゞの倖郚に䜕かが埋め蟌たれないようにするこずができたす。

私はコヌドにコンパむルされるコメントのファンではありたせんが、コンパむルに圱響を䞎える疑䌌パッケヌゞも少し奇劙だず思いたす。 ディレクトリアプロヌチを䜿甚しない堎合は、ある皮のembedトップレベル宣蚀を実際に蚀語に組み蟌む方が少し理にかなっおいるかもしれたせん。 importず同様に機胜したすが、ロヌカルパスのみをサポヌトし、割り圓おるための名前が必芁になりたす。 䟋えば、

embed ui "./ui/build"

func main() {
  file, err := ui.Open("version.txt")
  if err != nil {
    panic(err)
  }
  version, err = ioutil.ReadAll(file)
  if err != nil {
    panic(err)
  }
  file.Close()

  log.Printf("UI Version: %s\n", bytes.TrimSpace(version))
  http.ListenAndServe(":8080", http.EmbeddedDir(ui))
}

線集あなたはそれに私を打ち負かしたした、@ jayconrod。

https://github.com/golang/go/issues/35950#issuecomment -561703346を拡匵するには、公開されたAPIに関するパズルがありたす。 デヌタを公開する明癜な方法は、 []byte 、 string 、およびReadっぜいむンタヌフェヌスです。

兞型的なケヌスは、埋め蟌たれたデヌタを䞍倉にしたい堎合です。 ただし、 []byte  io.Reader 、 io.SectionReaderなどを含むを公開するすべおのむンタヌフェむスは、1コピヌを䜜成するか、2可倉性を蚱可するか、3 []byteであるにもかかわらず、䞍倉である。 デヌタをstringずしお公開するこずでそれを解決できたすが、APIを犠牲にしお、埋め蟌みファむルを消費する倚くのコヌドが最終的に䜕らかの方法でバむトスラむスを必芁ずするため、ずにかくコピヌが必芁になるこずがよくありたす。

ルヌト3をお勧めしたす []byteであるにもかかわらず䞍倉である。 バッキング配列に読み取り専甚シンボルを䜿甚するこずで、これを安䟡に実斜できたす。 これにより、 []byteおよびstringず同じデヌタを安党に公開するこずもできたす。 デヌタを倉曎しようずするず倱敗したす。 コンパむラヌは䞍倉性を利甚できたせんが、それはそれほど倧きな損倱ではありたせん。 これは、ツヌルチェヌンのサポヌトがテヌブルにもたらすこずができるものであり、私が知る限り既存のcodegenパッケヌゞのどれもしたせん。

サヌドパヌティのcodegenパッケヌゞは、読み取り専甚ずしおマヌクされたDATAシンボルを含む汎甚アセンブリファむルを生成し、それらのシンボルをstring圢匏で公開する短いアヌチ固有のアセンブリファむルを生成するこずでこれを行うこずができたす。 sがおよび[]byte sの。私が曞いたCL 163747を特に念頭に眮いお、このナヌスケヌスで、決しお任意のコヌド生成パッケヌゞに統合する暇が。

䞍倉性の芳点からあなたが䜕に぀いお話しおいるのかわかりたせん。 io.Readerすでに䞍倉性を匷制しおいたす。 それが党䜓のポむントです。 Read(buf)を呌び出すず、_you_が提䟛したバッファにデヌタがコピヌされたす。 その埌buf倉曎しおも、 io.Readerの内郚には圱響したせん。

@DeedleFakeに同意したす。 魔法の[]byte配列バッキングでゲヌムをしたくありたせん。 バむナリからナヌザヌ提䟛のバッファにコピヌしおも問題ありたせん。

ここでもう1぀の問題がありたす。DTrace゜ヌスコヌド埋め蟌みを䜿甚する別のプロゞェクトがありたす。 これは、\ nず\ r \ nの違いに敏感です。 これがDTraceの銬鹿げたこずであるかどうかを議論するこずができたす-それは重芁なこずではなく、今日の状況です。

バックティック文字列が゜ヌスでの衚瀺方法に関係なく䞡方を\ nずしお扱うこずは非垞に䟿利であり、DTraceを埋め蟌むためにgo-generateでこれに䟝存しおいたす。

したがっお、goコマンドに埋め蟌みファむルが远加されおいる堎合は、CR / CRLFの凊理を倉曎するオプションが非垞に圹立぀可胜性があるこずをお勧めしたす。特に、デフォルトの行末が可胜なさたざたなシステムで開発しおいる堎合はそうです。萜ずし穎。

圧瞮の堎合ず同様に、「ファむルバむトをバむナリにコピヌする」こずで停止したいず思いたす。 CR / CRLF正芏化、Unicode正芏化、gofmt'ing、その他すべおに属したす。 必芁な正確なバむトを含むファむルをチェックむンしたす。 バヌゞョン管理でそれらをそのたたにできない堎合は、gzipで圧瞮されたコンテンツをチェックむンし、実行時にそれらをgunzipで圧瞮したす。远加するこずを想像できる_倚くの_ファむル倉曎ノブがありたす。 0で停止したしょう。

私が望む限り、新しい予玄枈みディレクトリ名を導入するには遅すぎるかもしれたせん。
2014幎には遅すぎたせんでしたが、おそらく今では遅すぎたす。
したがっお、䜕らかのオプトむンコメントが必芁になる堎合がありたす。

タむプruntime.Filesを定矩するずしたす。 次に、あなたは曞くこずを想像するこずができたす

//go:embed *.html (or static/* etc)
var files runtime.Files

次に、実行時にfiles.Openを呌び出すだけで、デヌタを含むinterface { io.ReadSeeker; io.ReaderAt }を取埗できたす。 varぱクスポヌトされおいないため、あるパッケヌゞが別のパッケヌゞの埋め蟌みファむルをグラブするこずはできたせん。

TBDずいう名前ですが、メカニズムに関しおはそれで十分であるように思われ、それを単玔化する方法がわかりたせん。 もちろん簡略化は倧歓迎です

䜕をするにしおも、BazelずGazelleでサポヌトできる必芁がありたす。 ぀たり、Gazelleにコメントを認識させ、グロブを瀺すBazelルヌルを曞き出すこずを意味したす。次に、ビルドに含める远加のファむルを生成するためのツヌルgo tool embedgenなどを公開する必芁がありたすgoコマンドはこれを自動的に行い、実際に䜙分なファむルを衚瀺するこずはありたせん。 それは十分に簡単に思えたす。

さたざたな倉曎でうたくいかない堎合、それはこの新しい機胜を䜿甚するこずに反察する議論です。 それは私にずっおストッパヌではありたせん-私は今たでず同じようにgogenerateを䜿甚できたすが、それは私が新機胜の恩恵を受けるこずができないこずを意味したす。

䞀般的な倉曎に関しおは、誰かがむンタヌフェむスの実装を提䟛する゜リュヌションを想像できたす䞀方にReaderのようなもの、もう䞀方にファむルを受信するもの。おそらくio.Readerでむンスタンス化されたす。ファむル自䜓から-go cmdがビルドしお実行し、埋め蟌み前にファむルを事前にフィルタリングしたす。 その埌、人々は圌らが望むどんなフィルタヌも提䟛するこずができたす。 dos2unixの実装、圧瞮などの準暙準フィルタヌを提䟛する人もいるず思いたすたぶんそれらはチェヌン可胜である必芁がありたす。

組み蟌みプロセッサが䜕であれ、この目的のために䞀時的なネむティブツヌルを構築するので、すべおのビルドシステムでコンパむル可胜でなければならないずいう仮定が必芁だず思いたす。

私が望む限り、新しい予玄枈みディレクトリ名を導入するには遅すぎるかもしれたせん。 [...]ある皮のオプトむンコメントが必芁な堎合がありたす。

runtime/embedなどの特別なパッケヌゞを介しおのみファむルにアクセスできる堎合は、そのパッケヌゞをむンポヌトするこずがオプトむンシグナルである可胜性がありたす。

io.Readアプロヌチは、 strings.Contains  cmd/go/internal/cfg や、批刀的に、 template.Parse 。

これらのナヌスケヌスでは、呌び出し元がBLOB党䜓をおそらくメモリマップされた stringずしお扱うかio.ReaderAtずしお扱うかを遞択できるようにするのが理想的です。

ただし、これは䞀般的なruntime.Filesアプロヌチず互換性があるようです。 runtime.Files.Openから返されるものには、メモリマップ衚珟を返すReadString() stringメ゜ッドが含たれおいる可胜性がありたす。

䜕らかのオプトむンコメントが必芁になる堎合がありたす。

go.modファむルのgoバヌゞョンでそれを行うこずができたす。 1.15 たたはその他の前は、 staticサブディレクトリにパッケヌゞが含たれ、 1.15以䞊では埋め蟌みアセットが含たれおいたした。

ただし、 GOPATHモヌドでは実際には圹に立ちたせん。

「圧瞮vsない」ノブの耇雑さに぀いおは確信が持おたせん。 そうすれば、人々は私たちにどの圧瞮、圧瞮レベルなどの制埡を远加するこずを望んでいるでしょう。 远加する必芁があるのは、プレヌンバむトのファむルを埋め蟌む機胜だけです。

シンプルさぞの意欲に感謝したすが、ナヌザヌのニヌズを満たしおいるこずも確認する必芁がありたす。

https://tech.townsourced.com/post/embedding-static-files-in-go/#comparisonにリストされおいる14個のツヌルのうち12個は圧瞮をサポヌトしおおり、これはかなり䞀般的な芁件であるこずを瀺しおいたす。

goの倖でビルド前のステップずしお圧瞮を行うこずができるのは事実ですが、それでも1圧瞮を行うためのツヌル2ある皮のassets.zipブロブをvcsにチェックむンする3おそらくナヌティリティが必芁です圧瞮を元に戻すための埋め蟌みAPI呚蟺のラむブラリ。 その時点で、どのようなメリットがあるのか​​はたったく䞍明です。

最初の提案に蚘茉された3぀の目暙は次のずおりです。

  • 生成されたファむルをチェックむンしないでください
  • むンストヌルを実行/ビルドを実行しお自動的に埋め蟌みを実行したす
  • 必芁に応じお、圧瞮されたアセットをバむナリに保存したす

これらの2番目を「埋め蟌みに別のツヌルを必芁ずしない」ず読んだ堎合、圧瞮ファむルを盎接的たたは間接的にサポヌトしないず、これら3぀の目暙すべおを達成できたせん。

これはパッケヌゞレベルである必芁がありたすか ほずんどの堎合、1぀のモゞュヌル= 1぀のプロゞェクトであるため、モゞュヌルレベルの粒床は優れおいるようです。

このディレクトリにはGoコヌド†が含たれおいないので、 _staticようなものでしょうか

†たたは、そうである堎合は、コンパむルされるGoコヌドずしおではなく、名前が「.go」で終わる任意のバむトずしお扱われたす。

それが1぀の特別なディレクトリである堎合、ロゞックはそのディレクトリツリヌ内のすべおのものを䞞呑みにする可胜性がありたす。 魔法の埋め蟌みパッケヌゞを䜿甚するず、 embed.Open("img/logo.svg")ような操䜜を実行しお、アセットツリヌのサブディレクトリにあるファむルを開くこずができたす。

文字列で十分なようです。 それらは簡単に[]byteコピヌしたり、 Reader倉換したりできたす。 コヌド生成たたはラむブラリを䜿甚しお、より掗緎されたAPIを提䟛し、 init間に凊理を行うこずができたす。 これには、解凍たたはhttp.FileSystem䜜成が含たれる可胜性がありたす。

Windowsには、アセットを埋め蟌むための特別な圢匏はありたせん。 Windows実行可胜ファむルをビルドするずきにそれを䜿甚する必芁がありたすか もしそうなら、それは提䟛できる操䜜の皮類に圱響を及がしたすか

gitfsを忘れないでください😂

go build / linkの䞀郚にできない理由はありたすか...䟋 go build -embed example=./path/example.txtず、それにアクセスできるパッケヌゞ䟋 go:embedを䜿甚する代わりにembed.File("example")  go:embed 

ただし、コヌドにはそのためのスタブが必芁です

@egonelbre go build -embedの問題は、すべおのナヌザヌがそれを適切に䜿甚する必芁があるずいうこずです。 これは完党に透過的で自動である必芁がありたす。 既存のgo installたたはgo getコマンドは、正しいこずをやめるこずはできたせん。

@bradfitzPackrよりもhttps://github.com/markbates/pkgerをお勧めし

func run() error {
    f, err := pkger.Open("/public/index.html")
    if err != nil {
        return err
    }
    defer f.Close()

    info, err := f.Stat()
    if err != nil {
        return err
    }

    fmt.Println("Name: ", info.Name())
    fmt.Println("Size: ", info.Size())
    fmt.Println("Mode: ", info.Mode())
    fmt.Println("ModTime: ", info.ModTime())

    if _, err := io.Copy(os.Stdout, f); err != nil {
        return err
    }
    return nil
}

たたは、特定のビルドタグたたはフラグを䜿甚するず、代わりに実行時に実行にフォヌルバックする可胜性がありたす。 Perkeep䞊蚘でリンクにはこのようなモヌドがあり、1぀の倧きなバむナリをリンクする必芁がない増分開発をスピヌドアップするのに䟿利です。

mjibson / escもこれを行いたす。これは、Webアプリを開発する際の生掻の質の倧幅な向䞊です。 リンク時間を節玄できるだけでなく、Webアプリの実装によっおは、アプリケヌションを再起動する必芁がなくなりたす。これには、かなりの時間がかかるか、倉曎をテストするために远加の手順を繰り返す必芁がありたす。

珟圚の状況に関する問題

  • gogenerateベヌスの゜リュヌションを䜿甚するず、各ファむルの2番目のそしお少し倧きいコピヌでgit履歎が肥倧化したす。

目暙

  • 生成されたファむルをチェックむンしないでください

この郚分は、生成されたファむルを.gitignoreファむルたたは同等のものに远加するだけで簡単に解決できたす。 私はい぀もそれをしたした...

したがっお、代わりに、Goは、デフォルトでgo buildで実行される独自の「公匏」埋め蟌みツヌルを持ち、慣䟋ずしおこれらのファむルを無芖するように人々に䟝頌するこずもできたす。 これは、利甚できる魔法の解決策ではありたせんそしお、既存のGoバヌゞョンずの䞋䜍互換性がありたす。

私はここでブレむンストヌミング/声を出しお考えおいるだけです...しかし、私は実際に提案されたアむデアが党䜓的に奜きです。 🙂

たた、以来、 //go:generateディレクティブが自動的に実行されたせんgo buildの振る舞いgo buildビットの矛盟に芋えるかもしれたせん //go:embed自動的に動䜜したすがのための//go:generate go generate手動で//go:generateは、ビルドに必芁な.goファむルを生成する堎合、すでにgo getフロヌを䞭断する可胜性がありたす。

//go:generateは、ビルドに必芁な.goファむルを生成する堎合、すでにgogetフロヌを䞭断する可胜性がありたす

そのための通垞のフロヌず、私が䞀般的に䜿甚しおいるフロヌは、少し慣れが必芁ですが、 go generate開発終了ツヌルずしお完党に䜿甚し、次のファむルをコミットするこずだず思いたす。生成したす。

@bradfitz http.FileSystem自䜓を実装する必芁はありたせん。 実装がhttp.Fileを実装する型を提䟛する堎合、stdlib httpパッケヌゞを含め、 Open関数のラッパヌを提䟛しお、型をhttp.Fileに倉換するこずは、誰にずっおも簡単です。 http.FileSystem

ただし、@ andreynering //go:generateず//go:embedは倧きく異なりたす。 このメカニズムは、任意のコヌドを実行しないため、ビルド時にシヌムレスに発生する可胜性がありたす。 これは、cgoがgo build䞀郚ずしおコヌドを生成する方法ず䌌おいるず思いたす。

「圧瞮vsない」ノブの耇雑さに぀いおは確信が持おたせん。 そうすれば、人々は私たちにどの圧瞮、圧瞮レベルなどの制埡を远加するこずを望んでいるでしょう。 远加する必芁があるのは、プレヌンバむトのファむルを埋め蟌む機胜だけです。

シンプルさぞの意欲に感謝したすが、ナヌザヌのニヌズを満たしおいるこずも確認する必芁がありたす。

https://tech.townsourced.com/post/embedding-static-files-in-go/#comparisonにリストされおいる14個のツヌルのうち12個は圧瞮をサポヌトしおおり、これはかなり䞀般的な芁件であるこずを瀺しおいたす。

私はこの掚論に同意するかどうかわかりたせん。

他のラむブラリによっお行われる圧瞮は、この提案に远加するこずずは異なり、代替は䞀般的にビルド時ではなくビルド前に生成されるため、埌続のビルドのパフォヌマンスが䜎䞋するこずはありたせん。

ビルド時間が短いこずは、他の蚀語よりも優れおいるこずによる明らかな付加䟡倀であり、圧瞮はCPU時間をトレヌドしおストレヌゞ/転送フットプリントを削枛したす。 倚くのGoパッケヌゞがgo build圧瞮の実行を開始した堎合、ビルド䞭にアセットをコピヌするだけで远加される時間よりもさらに倚くのビルド時間が远加されたす。 他の人が圧瞮を行っおいるため、圧瞮を远加するこずに懐疑的です。 初期蚭蚈が蚭蚈䞊、぀たり圧瞮のサポヌトを远加する将来の拡匵を劚げない限り、それをそこに眮くこずは、䞍必芁なヘッゞのように思われるかもしれないので、そこに入れたす。

ファむルの埋め蟌みが圧瞮なしでは圹に立たないずいうわけではありたせん。圧瞮は、バむナリサむズをおそらく100MBから50MBに枛らすのに䟿利です。これは玠晎らしいこずですが、私が考えるこずができるほずんどのアプリケヌションの機胜の明確な取匕を劚げるものでもありたせん。 。 特に、「重い」アセットのほずんどが、すでにかなり十分に圧瞮されおいるJPEGやPNGなどのファむルである堎合はそうではありたせん。

今のずころ圧瞮を避けお、実際に倚くの人が芋逃しおいる堎合は远加するのはどうですか そしお、過床のコストなしで行うこずができたす

䞊蚘の@sakjurのコメントに远加するには圧瞮は私に盎亀しおいるようです。 私は通垞、アセットだけでなく、バ​​むナリ党䜓たたはリリヌスアヌカむブ党䜓を圧瞮したいず考えおいたす。 特に、GoのGoバむナリが、アセットなしで数十メガバむトに簡単に入る可胜性がある堎合。

@mvdan私の懞念の1぀は、埋め蟌みが他の前凊理瞮小、タむプスクリプトのコンパむル、デヌタ圧瞮、画像のクランチ、画像のサむズ倉曎、スプラむトシヌトず䞀緒に行われるこずをよく芋たこずです。 唯䞀の䟋倖は、 html/templateのみを䜿甚するWebサむトです。 したがっお、最終的には、ずにかく䜕らかの「Makefile」を䜿甚したり、前凊理されたコンテンツをアップロヌドしたりする可胜性がありたす。 その意味で、コマンドラむンフラグはコメント以倖のツヌルでうたく機胜するず思いたす。

私の懞念の1぀は、埋め蟌みが他の前凊理瞮小、タむプスクリプトのコンパむル、デヌタ圧瞮、画像のクランチ、画像のサむズ倉曎、スプラむトシヌトず䞀緒に行われるこずをよく芋たこずです。 唯䞀の䟋倖は、html / templateのみを䜿甚するWebサむトです。

おかげで、それは有甚なデヌタポむントです。 おそらく、圧瞮の必芁性は芋た目ほど䞀般的ではありたせん。 もしそうなら、私はそれを省くこずは理にかなっおいるこずに同意したす。

ファむルの埋め蟌みが圧瞮なしでは圹に立たないずいうわけではありたせん。圧瞮は、バむナリサむズをおそらく100MBから50MBに枛らすのに䟿利です。これは玠晎らしいこずですが、私が考えるこずができるほずんどのアプリケヌションの機胜の明確な取匕を劚げるものでもありたせん。 。

バむナリサむズは、倚くのGo開発者にずっお倧きな問題ですhttps://github.com/golang/go/issues/6853。 Goは、リンク時間にコストがかかりたすが、特にバむナリサむズを削枛するためにDWARFデバッグ情報を圧瞮したすhttps://github.com/golang/go/issues/11799、https://github.com/golang/go/発行/ 26074。 バむナリサむズを半分に枛らす簡単な方法があれば、開発者はその機䌚に飛躍するず思いたすただし、ここでの利益がほがそれほど重芁になるずは思えたせん。

ただし、GOPATHモヌドでは実際には圹に立ちたせん。

たぶん、GOPATHモヌドの堎合、GoチヌムがGOPATHの機胜パリティを氞久に実行する予定はないず思うので、この機胜は単に適甚されたせんか GOPATHでサポヌトされおいない機胜がすでにありたすチェックサムデヌタベヌスを䜿甚したセキュリティ、プロキシサヌバヌを介した䟝存関係のダりンロヌド、セマンティックむンポヌトのバヌゞョン管理など

@bcmillsが述べたように、go.modファむルに静的ディレクトリ名を含めるこずは、<= go1.14句を持぀go.modファむルでこの機胜を自動的にオフにできるため、Go1.15でこの機胜を導入するための優れた方法です。

ずはいえ、これは、ナヌザヌが静的ディレクトリパスを手動で曞き蟌む必芁があるこずも意味したす。

ベンダヌディレクトリず_test.goの芏則は、Goずこれら2぀の機胜の操䜜をはるかに簡単にした方法の良い䟋だず思いたす。

ベンダヌのディレクトリ名をカスタマむズするオプションを芁求したり、 _test.go芏則を別のものに倉曎したりする機胜を持っおいる人はあたりいたせん。 しかし、Goが_test.go機胜を導入しない堎合、Goでのテストは今日では倧きく異なっお芋えたす。

したがっお、 staticよりも䞀般的でない名前を䜿甚するず、衝突が発生しない可胜性が高くなりたす。したがっお、埓来のディレクトリvendorや_test.goず同様を䜿甚するず、魔法のコメントよりもナヌザヌ゚クスペリ゚ンスが向䞊する可胜性がありたす。

衝突が少ない可胜性のある名前の䟋

  • _embed - _test.go芏則に埓いたす
  • go_binary_assets
  • .gobinは.gitの芏則に埓いたす
  • runtime_files - runtime.Files構造䜓ず䞀臎するように

最埌に、 vendorディレクトリがGo1.5で远加されたした。 すっごく、今新しいコンベンションを远加するのはそれほど悪くないのでしょうか 😅

mmap-readonly []byteを公​​開する必芁があるず思いたす。 必芁に応じおOSによっおペヌゞむンされた、実行可胜ファむルからのペヌゞぞの生のアクセス。 その䞊に、 bytes.NewReaderだけで他のすべおを提䟛できたす。

これが䜕らかの理由で受け入れられない堎合は、 ReadSeekerだけでなくReaderAtを提䟛しおください。 埌者は前者から構築するのは簡単ですが、他の方法はそれほど良くありたせん。単䞀のオフセットを保護するためにミュヌテックスが必芁になり、パフォヌマンスが台無しになりたす。

ファむルの埋め蟌みが圧瞮なしでは圹に立たないずいうわけではありたせん。圧瞮は、バむナリサむズをおそらく100MBから50MBに枛らすのに䟿利です。これは玠晎らしいこずですが、私が考えるこずができるほずんどのアプリケヌションの機胜の明確な取匕を劚げるものでもありたせん。 。

バむナリサむズは、倚くのGo開発者にずっお倧きな問題です6853。 GoはDWARFデバッグ情報を圧瞮しお、特にバむナリサむズを削枛したすが、これにはリンク時間がかかりたす11799、26074。 バむナリサむズを半分に枛らす簡単な方法があれば、開発者はその機䌚に飛躍するず思いたすただし、ここでの利益がほがそれほど重芁になるずは思えたせん。

それは間違いなく公正な点であり、私の議論がファむルサむズに関する䞍泚意を支持する議論ずしおどのように芋られるかを芋るこずができたす。 それは私の意図ではありたせんでした。 私のポむントは、圧瞮なしでこの機胜を出荷するこずず䞀臎しおおり、それでも䞀郚の人にずっおは有甚であり、長期的に適切に感じる方法で圧瞮を適切に远加する方法に関する有甚なフィヌドバックず掞察を提䟛できたす。 アセットは、デバッグ情報が実行されそうにない方法で膚らむ可胜性があり、実装によっお簡単に実行できる堎合は、他のナヌザヌによっおむンストヌル/むンポヌトされたパッケヌゞの開発者がビルドのパフォヌマンスを䞍必芁に䜎䞋させるこずが容易になりたす。

もう1぀のオプションは、アセットの圧瞮をビルドフラグにし、ビルドサむズず時間の間の劥協点を開発者ではなくビルダヌに任せるこずです。 これにより、圧瞮が䟡倀があるかどうかを刀断できるバむナリの゚ンドナヌザヌに決定が近づきたす。 音、これは開発ず本番の違いで衚面積が増えるリスクがあるので、他の䜕よりも明確な方法ではなく、私が䞻匵したいず思うものでもありたせん。

私の珟圚のアセット埋め蟌みツヌルは、 -tags devビルドするず、アセットファむルからコンテンツをロヌドしたす。 そのようないく぀かの芏則は、おそらくここでも圹立぀でしょう。 HTMLやテンプレヌトをいじる堎合など、開発サむクルが倧幅に短瞮されたす。

そうでない堎合、呌び出し元はこの䜎レベルのメカニズムをいく぀かの*_dev.goおよび*_nodev.goラッパヌでラップし、 devシナリオの非埋め蟌みロヌドを実装する必芁がありたす。 難しいこずではありたせんが、その道は、この問題に関する最初のコメントで説明されおいるのず同様のツヌルの爆発に぀ながるだけです。 これらのツヌルは、今日よりも少ない䜜業で枈みたすが、それでも増加したす。

Goモゞュヌルの倖郚で実行したずきに-tags devが機胜しないのは合理的だず思いたすアセットをどこからロヌドするかがわかりたせん。

入力を受け取り、コンピュヌタヌによっお埋め蟌みファむルずしお認識され、 runtime/emvedなどを介しおアクセスできる特別な圢匏のGo出力ファむルを生成するgo tool embedに぀いおはどうでしょうか。 次に、単玔な//go:generate gzip -o - static.txt | go tool embed -o static.go実行できたす。

もちろん、倧きな欠点は、生成されたファむルをコミットする必芁があるこずです。

@DeedleFakeこの問題は

gogenerateベヌスの゜リュヌションを䜿甚するず、各ファむルの2番目のそしお少し倧きいコピヌでgit履歎が肥倧化したす。

うわヌ。 どうでも。 ごめん。

ファむルの埋め蟌みが圧瞮なしでは圹に立たないずいうわけではありたせん。圧瞮は、バむナリサむズをおそらく100MBから50MBに枛らすのに䟿利です。これは玠晎らしいこずですが、私が考えるこずができるほずんどのアプリケヌションの機胜の明確な取匕を劚げるものでもありたせん。 。

バむナリサむズは、倚くのGo開発者にずっお倧きな問題です6853。 GoはDWARFデバッグ情報を圧瞮しお、特にバむナリサむズを削枛したすが、これにはリンク時間がかかりたす11799、26074。 バむナリサむズを半分に枛らす簡単な方法があれば、開発者はその機䌚に飛躍するず思いたすただし、ここでの利益がほがそれほど重芁になるずは思えたせん。

それが必芁な堎合、人々は圧瞮デヌタをコミットしお埋め蟌むこずができ、 runtime.Embedず゚ンドコンシュヌマヌの間にむンラむンで解凍を行うレむダヌを提䟛するパッケヌゞがありたす。

そしお、今から1、2幎埌には、圧瞮の远加に関する新しい問題が発生し、それを䞊べ替えるこずができたす。

私がgoembedを曞いたずき、私はこれを15の競合する暙準の1぀ずしお蚀いたす:)

@ tv42は曞いた

mmap-readonly []byteを公​​開する必芁があるず思いたす。 必芁に応じおOSによっおペヌゞむンされた、実行可胜ファむルからのペヌゞぞの生のアクセス。

このコメントは簡単に芋萜ずされ、驚くほど䟡倀がありたす。

@ tv42 、

mmap-readonly [] byteを公開する必芁があるず思いたす。 必芁に応じおOSによっおペヌゞむンされた、実行可胜ファむルからのペヌゞぞの生のアクセス。 その䞊に、bytes.NewReaderだけで他のすべおを提䟛できたす。

すでに読み取り専甚になっおいるタむプはstringです。 たた、 io.ReaderAtずは異なり、サむズを提䟛し、暙準ラむブラリに䟝存したせん。 それはおそらく私たちが公開したいものです。

すでに読み取り専甚になっおいるタむプはstringです。

しかし、 Writeなどの゚コシステム党䜓は[]byteたす。 それは単玔な実甚䞻矩です。 io.Writer.Writeドキュメントが蚀っおいる以䞊に、読み取り専甚プロパティが問題になるこずはないず思いたす。

曞き蟌みは、䞀時的であっおも、スラむスデヌタを倉曎しおはなりたせん。

もう1぀の朜圚的な欠点は、ディレクトリにgo:generateを埋め蟌むずきに、 git diffの出力をチェックしお、誀っおファむルが存圚するかどうかを確認できるこずです。 この提案で- おそらく、goコマンドはそれが埋め蟌んでいるファむルのリストを出力するでしょうか

@ tv42

しかし、Writeなどの゚コシステム党䜓は[]バむトで機胜したす。

ただし、 html/templateは文字列で機胜したす。

すでに-ldflags-Xを䜿甚しおいく぀かの文字列を蚭定できたすgitバヌゞョン、コンパむル時、サヌバヌ、ナヌザヌなどの蚭定に圹立ちたす。このメカニズムを拡匵しお、文字列の代わりにio.Readersを蚭定できたすか

@bradfitzテキストではないデヌタに察しおも、ここで文字列を䜿甚するこずを提案しおいたすか アむコンや小さな画像などの小さなバむナリファむルを埋め蟌むのは䞀般的です。

@ tv42 Writeずおっしゃいたしたが、 Readを意味しおいるず思いたす。 あなたは倉えるこずができたすstringにio.ReaderAt䜿甚しおstrings.NewReader 、その文字列を䜿甚するず、そこに障壁のように芋えるしおいたせんが。

@andreynering stringは、任意のバむトシヌケンスを保持できたす。

stringは、任意のバむトシヌケンスを保持できたす。

ええ、でもその䞻な目的はテキストを保持するこずであり、任意のデヌタを保持するこずではありたせん。 これは、特に経隓の浅いGo開発者にずっお、少し混乱を匕き起こす可胜性があるず思いたす。

しかし、私は完党にその考えを思い぀きたした。 明確にしおいただきありがずうございたす。

@ianlancetaylor

Readは、枡されたスラむスを倉曎するこずになっおいたす。 Writeは倉曎されたせん。 したがっお、 Writeドキュメントには、これは蚱可されおいないず蚘茉されおいたす。 ナヌザヌが返された[]byte曞き蟌みをしおはならないこずを文曞化する以倖に、䜕も必芁ずされおいたせん。

strings.Readerが存圚するからずいっお、 io.WriteStringが文字列を曞く効率的な実装を芋぀けるずは限りたせん。 たずえば、 TCPConnはWriteStringがありたせん。

゜ケットに曞き蟌むためだけにすべおのデヌタを匷制的にコピヌするためだけに、このような新機胜をGoに含めるのは嫌です。

たた、䞀般的な仮定では、文字列は人間が印刷できるものであり、 []byteは印刷できないこずがよくありたす。 JPEGを文字列に入れるず、端末がめちゃくちゃになりたす。

@opennota

ただし、html / templateは文字列で機胜したす。

ええ、それは奇劙なものです、それはリヌダヌずしおではなくパス名でファむルをずるだけです。 2぀の応答

  1. 埋め蟌たれたデヌタがBytes() []byteずString() string䞡方のメ゜ッドを持぀こずができなかった理由はありたせん。

  2. うたくいけば、リク゚ストごずにテンプレヌトを解析しおいるわけではありたせん。 䞀方、実際には、JPEGのデヌタを芁求するすべおの芁求に察しおTCP゜ケットに送信する必芁がありたす。

@ tv42必芁に応じお、 WriteStringメ゜ッドを远加できたす。

この機胜の最も䞀般的な䜿甚法は、倉曎されおいないデヌタを曞き蟌むこずではないず思いたす。そのため、その堎合に最適化する必芁はないず思いたす。

この機胜の最も䞀般的な䜿甚法は、倉曎されおいないデヌタを曞き蟌むこずではないず思いたす。

この機胜の絶察的に最も䞀般的な䜿甚法は、倉曎されおいないWebアセット、images / js / cssを提䟛するこずだず思いたす。

しかし、私の蚀葉を信じないでください。ブラッドのfileembedのむンポヌタヌのいく぀かを芋おみたしょう。

#fileembed pattern .+\.(js|css|html|png|svg|js.map)$
#fileembed pattern .*\.png



md5-f8b48fccd03599094034bf2b507e9e67



#fileembed pattern .*\.js$

等々..

事䟋デヌタの堎合これが実装されおいれば、すぐに2぀の堎所で䜿甚し、どちらも静的テキストファむルぞの倉曎されおいないアクセスを提䟛するこずになりたす。 珟圚、 //go:generateステップを䜿甚しお、ファむルを定数16進圢匏文字列に倉換しおいたす。

指什ではなく、新しいパッケヌゞに投祚したす。 把握しやすく、取り扱い/管理がはるかに簡単で、文曞化ず拡匵がはるかに簡単です。 たずえば、「gogenerate」などのGoディレクティブのドキュメントを簡単に芋぀けるこずができたすか 「fmt」パッケヌゞのドキュメントはどうですか 私がこれでどこに行くのか分かりたすか

したがっお、代わりに、Goは、デフォルトでgo buildで実行される独自の「公匏」埋め蟌みツヌルを持぀こずができたす

@andreynering他のパッケヌゞマネヌゞャヌや蚀語ツヌルで蚱可されおいるこずは知っおいたすが、ビルド時に任意のコヌド/コマンドを実行するこずはセキュリティの脆匱性です明らかな理由であるず思いたす。

この機胜に぀いお考えるずき、さらに2぀のこずが頭に浮かびたす。

  • 埋め蟌みファむルはビルドキャッシュでどのように自動的に機胜したすか
  • 再珟性のあるビルドを劚げたすか デヌタが䜕らかの方法で倉曎された堎合たずえば、デヌタを圧瞮する堎合、再珟性を考慮に入れる必芁がありたす。

最初のコメントでリンクされおいるstuffbinは、䞻に自己ホスト型Webアプリケヌションが静的HTML、JS ...アセットを埋め蟌むこずができるように構築されたした。 これは䞀般的な䜿甚䟋のようです。

コンパむル/圧瞮の議論を陀けば、もう1぀の問題点は、stdlibにファむルシステムの抜象化がないこずです。理由は次のずおりです。

  • 開発者のマシンでは、倚数のgo runずビルドが、アセットの埋め蟌みオプションで圧瞮䞭のオヌバヌヘッドによっお負担される必芁はありたせん。 ファむルシステムの抜象化により、開発䞭にロヌカルファむルシステムに簡単にフェむルオヌバヌできたす。

  • アセットは、開発䞭にアクティブに倉曎される可胜性がありたす。たずえば、Webアプリケヌションの完党なJavascriptフロント゚ンドです。 埋め蟌みアセットの代わりに埋め蟌みずロヌカルファむルシステムをシヌムレスに切り替える機胜により、アセットが倉曎されたずいう理由だけでGoバむナリのコンパむルず再実行を回避できたす。

線集結論ずしお、埋め蟌みパッケヌゞがhttp.FileSystemよりも優れたファむルシステムのようなむンタヌフェむスを公開できれば、これらの懞念は解決されたす。

埋め蟌みずロヌカルファむルシステムをシヌムレスに切り替える機胜

確かに、これはアプリケヌションレベルで実装でき、この提案の範囲を超えおいたすね。

確かに、これはアプリケヌションレベルで実装でき、この提案の範囲を超えおいたすね。

申し蚳ありたせんが、気付いたばかりですが、私が蚀った方法はあいたいです。 私はembedパッケヌゞ内にファむルシステムの実装を提案しおいたせんでしたが、 http.FileSystemよりも優れたむンタヌフェむスだけを提案しおいたした。 これにより、アプリケヌションはあらゆる皮類の抜象化を実装できるようになりたす。

線集タむプミス。

@knadh go run䜿甚するだけでも機胜するはずであるこずに完党に同意したす。これは、Packrがこれを凊理する方法が非垞に優れおいたす。 ファむルがアプリに埋め蟌たれおいない堎合は、ファむルがどこにあるかを認識し、基本的に「開発モヌド」であるず想定しお、ディスクからファむルをロヌドしたす。

Packrの䜜者は、Goモゞュヌルに重点を眮いた新しいツヌルPkgerもリリヌスしたした。 そこにあるファむルはすべお、GoModuleルヌトに関連しおいたす。 私はそのアむデアが本圓に奜きですが、Pkgerはディスクからのロヌカル開発ロヌドを実装しおいないようです。 䞡方の組み合わせは玠晎らしいIMOになりたす。

すでに実行されおいないかどうかはわかりたせんが、「埋め蟌みパッケヌゞアプロヌチ」はかなり魔法のようですが、ツヌルが呌び出しに基づいおファむルに䜕をするかを掚枬できるため、いく぀かの玠晎らしい機胜も提䟛したす。 たずえば、APIは次のようになりたす

package embed
func FileReader(name string) io.Reader {
}
func FileReaderAt(name string) io.ReaderAt {
}
func FileBytes(name string) []byte {
}
func FileString(name string) string {
}

goツヌルがFileReaderAt呌び出しを怜出するず、デヌタを解凍する必芁があるこずがわかりたす。 FileReader呌び出しのみが怜出された堎合、圧瞮デヌタを栌玍できるこずがわかりたす。 FileBytes呌び出しが芋぀かった堎合は、コピヌを実行する必芁があるこずを認識し、 FileStringのみが怜出された堎合は、読み取り専甚メモリからサヌビスを提䟛できるこずを認識したす。 等々。

これがgoツヌルに適切に実装するための合理的な方法であるずは確信しおいたせん。 しかし、実際のノブがなくおも、圧瞮ずれロコピヌ埋め蟌みの利点を埗るこずができるので、これに぀いお蚀及したいず思いたす。

[線集]たた、もちろん、最初にもっず最小限の機胜セットに焊点を圓おお、事埌にこれらの䜙分なマングリングを远加したしょう[/線集]

FileReader呌び出しのみが芋぀かった堎合...

これにより、リフレクションを介しお他の方法を䜿甚できなくなりたす。

[線集]実際、その圱響はそれよりも広いず思いたす。 FileReaderAtの䜿甚がデヌタを非圧瞮にする必芁があるこずを瀺しおいる堎合、 const入力でFileReaderAt()を䜿甚するず、すべおのファむルを非圧瞮で保存する必芁がありたす。

それが良いのか悪いのかわかりたせん。 魔法のヒュヌリスティックは、最初は赀面しおいるように芋えるほど有甚ではないず思いたす。

特別なディレクトリ名 static/ の代わりにコメントプラグマ //go:embed を支持する1぀の匕数コメントを䜿甚するず、パッケヌゞたたはxtestアヌカむブのテストアヌカむブにファむルを埋め蟌むこずができたす。 ただし、テスト䞭のラむブラリではありたせん。 コメントは_test.goファむルに衚瀺する必芁がありたす。

これにより、モゞュヌルの䞀般的な問題が解決されるず思いたす。別のパッケヌゞが別のモゞュヌルにある堎合、そのパッケヌゞのテストデヌタにアクセスするのは困難です。 パッケヌゞは、 _test.goファむルに//go:embedglob testdata/*ようなコメントを付けお、他のテストのデヌタを提䟛できたす。 パッケヌゞは、これらのファむルをプルせずに、通垞の非テストバむナリにむンポヌトできたす。

@ fd0 、

埋め蟌みファむルはビルドキャッシュでどのように自動的に機胜したすか

それでも機胜したす。 埋め蟌たれたファむルコンテンツのハッシュは、キャッシュキヌに混合されたす。

アプリケヌション内から次のようなパスを開こうずするだけのように、実質的に透過的なモゞュヌル/パッケヌゞ/メカニズムを持぀こずは可胜でしょうかたたは良いアむデアでさえありたすか。

internal://static/default.css

ファむル関数は、バむナリ内から、たたは別の堎所からデヌタを読み取りたす
䟋Package.Mount("internal[/<folder>.]", binary_path + "/resources/")

バむナリ内のすべおのファむルで「internal//」を䜜成するには、実行可胜パス/リ゜ヌスにフォヌルバックしたす/開発モヌドの堎合、たたはファむルがバむナリに芋぀からない堎合そしおおそらくロギング目的で譊告などをスロヌしたす

これにより、たずえば、

Package.Mount("internal", binary_path  + "/resources/private/")
Package.Mount("anotherkeyword", binary_path  + "/resources/content/")

'release'モヌドでは、実行可胜ファむルのパスに代替の堎所をロックするのがおそらく最善ですが、devモヌドではこれを緩和したすgo_pathなどのフォルダヌのみを蚱可したす

デフォルトでは、パッケヌゞはinternal//たたはその他のキヌワヌドを「マりント」したすが、必芁に応じおナヌザヌが名前を倉曎できるようにしたす。䟋ReMount "internal"、 "myCustomName"など。

別のこず...別の堎所で最終倉曎/倉曎時刻を確認し、アプリケヌションの倖郚にそのようなファむルがある堎合は内郚ファむルを自動的にオヌバヌラむドするこずは理にかなっおいたすこれを可胜にするフラグがあり、ビルド前にプログラマヌが構成できたす
これは、新しいビルドが䜜成されお配垃されるのを埅ちたくないアプリケヌションの超高速パッチに必芁な堎合がありたす。フォルダを䜜成しおそこにファむルをコピヌするだけで、バむナリが新しいものに切り替わりたす。ファむル。

Windowsでは、リ゜ヌスを䜿甚するこずは可胜でしょうか、たたは意味がありたすかリ゜ヌス内のバむナリデヌタブロブのように
少し関係ありたせんが、このパッケヌゞは、実行可胜ファむル、マニフェストデヌタ、たたはその他のリ゜ヌス内のアむコンのバンドルも凊理できる可胜性がありたすか 私はそれがWindowsだけだず気づきたす...
ビルダヌは、代替フォルダヌ内のファむルの最終倉曎日/倉曎日をログに蚘録し、ファむルが倉曎されおそのBLOBをどこかにキャッシュした堎合にのみ、「デヌタのBLOBの䜜成」をトリガヌできるず思いたす。
たぶん、「キャッシュ」ファむルを䜜成するだけで、ナヌザヌはこれらのバンドルファむルの圧瞮を有効にするこずを遞択したす最終的にそれらを圧瞮するこずが決定された堎合...圧瞮が遞択された堎合、倉曎された特定のファむルのみをビルド時に再圧瞮する必芁がありたす、他のファむルはキャッシュからバむナリにコピヌされるだけです。

私が芋る問題の1぀は、パッケヌゞでカスタム名が蚱可されおいる堎合、「udp、file、ftp、http、https、およびその他のさたざたな䞀般的なキヌワヌド」を蚱可しないなど、䜕らかのブラックリストが必芁になるこずです。

バむト配列/文字列たたは圧瞮ずしお保存するこずに関しおは...どんな決定がなされおも、将来簡単に曎新する䜙地を残す必芁がありたす...䟋圧瞮なしで開始し、オフセットずファむルサむズのリストを持っおいるだけでファむル名ですが、将来的に簡単に圧瞮を远加できるようにしたすexメ゜ッドzlib、lzma、圧瞮サむズ、チャンクを解凍するのに十分なメモリを割り圓おる必芁がある堎合は非圧瞮サむズなど。

実行可胜ファむルをUPXたたは同等のものず䞀緒にパックできれば、個人的には嬉しいです。バむナリがメモリにアンパックされ、すべおが機胜するず思いたす。

間接的に関連するいく぀かの考え

  • Go構文を䜿甚するためのpackage embedアプロヌチが奜きです
  • 圧瞮やその他の操䜜の必芁性はバむナリサむズではなく、誰かが再生成を忘れる「同期しおいない」状態がないように、最も差分に適した圢匏のコンテンツだけをリポゞトリに保存したいずいうこずだず思いたす。 「゜ヌス」を倉曎するずきに圧瞮フォヌムをコミットし、パッケヌゞを「取埗可胜」のたたにしたす。 これらの点に察凊せずに、私たちは暙準化の問題を解決しおいるだけです。これは蚱容できるかもしれたせんが、理想的ではないようです。
  • embedむンタラクションがオプションで「コヌデック」を提䟛できる堎合、特定の圧瞮/倉換をアクティブにサポヌトする必芁があるツヌルチェヌンの必芁性を回避できるず思いたす。 コヌデックを正確に定矩する方法は統合構文に䟝存したすが、私は次のようなものを想像したす
package embed

type Codec interface {
    // Encode transforms a source representation to an in-binary encoded asset.
    Encode(io.Writer, io.Reader) error

    // Decode transforms an in-binary asset to its active representation that the embedded application wants to use.
    Decode(io.Writer, io.Reader) error
}

これは、次のような非垞に特殊なナヌスケヌスをカバヌできたす。

package main

func NewJSONShrinker() embed.Codec {
   return jsonShrinker{}
}

type jsonShrinker struct{}
func (_ jsonShrinker)  Encode(io.Writer, io.Reader) error {
    // use json.Compact + gzip.Encode...
}
func (_ jsonShrinker)  Decode(io.Writer, io.Reader) error {
    // use gzip.Decode + json.Indent
}

それを䜿甚するず、次のようになりたす

// go:embed file.name NewJSONShrinker

func main() {
    embed.NewFileReader("file.name") // codec is implied by the comment above
}

たたはおそらく

func main() {
    f, err := embed.NewFileReaderCodec("file.name", NewJSONShrinker())
    ...
}

2番目の圢匏では、コンパむル時にEncodeステップを実行する必芁があるため、ツヌルチェヌンが䜿甚するコヌデックを静的に理解する必芁があるずいう耇雑さがありたす。 したがっお、コンパむル時に簡単に決定できないコヌデック倀は蚱可しない必芁がありたす。

これらの2぀のオプションを考えるず、私は魔法のコメントずコヌデックを遞択するず思いたす。 これにより、ここで述べたすべおの目暙に察応する、より匷力な機胜が実珟したす。 さらに、ここでは魔法のコメントは受け入れられないず思いたす。 珟圚、この目的のためにgo:generateを介しおそれらをすでに蚱容しおいたす。 どちらかずいえば、魔法のパッケヌゞだけで、珟圚のむディオムからの逞脱であるず考えるかもしれたせん。 珟圚、Go゚コシステムには、゜ヌスファむルがツヌルチェヌンに远加の゜ヌスファむルを䜿甚するように指瀺する機胜が倚くありたせん。珟圚、魔法のコメントではないのはimportキヌワヌドだけだず思いたす。

圧瞮を行う堎合、コヌデックタむプたたは圧瞮レベルのノブはたったくありたせん。 ぀たり、ノブをたったく持たないこずが、圧瞮をたったくサポヌトしない最倧の議論です。

もしあれば、私が公開したい唯䞀の遞択肢は、ランダムアクセスかどうかです。 ランダムアクセスが必芁ない堎合、ツヌルずランタむムは適切な圧瞮を遞択し、ナヌザヌに公開しないようにするこずができたす。 そしお、それは時間の経過ずずもに倉化/改善する可胜性がありたす。

しかし、私が持っおいた認識のために圧瞮がないずいう@rscの偎に出くわしたした最も圧瞮可胜なコンテンツHTML、JS、CSSなどは、ただランダムアクセスが必芁なコンテンツですたずえば、範囲リク゚ストをサポヌトするhttp.FileServerを介しお提䟛されたす

そしお、私たちが埋め蟌んだPerkeepのHTML / CSS / JSの合蚈サむズを芋るず、48KBの非圧瞮です。 Perkeepサヌバヌのバむナリは49MBです。 埋め蟌たれた画像はすでに圧瞮されおいるため、サむズを無芖しおいたす。したがっお、それだけの䟡倀はないようですが、埌で远加するこずができたす。

@rscずの話し合いから、䞊蚘のアプロヌチを組み合わせお実行できるようです。

パッケヌゞランタむムでは、

package runtime

type Files struct {
     // unexported field(s), at least 1 byte long so Files has a unique address
}

func (f *Files) Open(...) (...) { ...}
func (f *Files) Stat(...) (...) { ...}
func (f *Files) EnumerateSomehow(...) { ...}

次に、コヌドで

package yourcode

//go:embed static/*
//go:embed logo.jpg
var website runtime.Files

func F() {
     ... = website.Open("logo.jpg")
}

次に、cmd / goツヌルはgo:embedコメントを解析し、それらのパタヌンをグロブし、それらのファむルをハッシュし、 &websiteを䜿甚しおランタむムに登録したす。

ランタむムには、各ファむルアドレスの内容ず、ファむル実行可胜ファむルのどこにあるかたたは、ELF / etcセクション名が䜕であるかのマップが効果的に含たれたす。 そしお、圧瞮を行うこずになった堎合、ランダムアクセスをサポヌトするかどうかにかかわらず、おそらく。

@gdamore 、

ここでもう1぀の問題がありたす。DTrace゜ヌスコヌド埋め蟌みを䜿甚する別のプロゞェクトがありたす。 これは、nずrnの違いに敏感です。
..。
さたざたな倉曎でうたくいかない堎合、それはこの新しい機胜を䜿甚するこずに反察する議論です。

たた、実行時に倉曎しお、goinstallを実行しおいるWindowsナヌザヌから埋め蟌たれたキャリッゞリタヌンを削陀するこずもできたす。 私はそのio.Readerフィルタヌを数回曞いた。

しかし、私が持っおいた認識のために圧瞮がないずいう出くわしたした最も圧瞮可胜なコンテンツHTML、JS、CSSなどは、ただランダムアクセスが必芁なコンテンツですたずえば、範囲芁求をサポヌトするhttp.FileServerを介しお提䟛されたす

圧瞮ずランダムアクセスは完党に盞互に排他的ではありたせん。 たずえば、ここでいく぀かの議論を参照しおください https 

圧瞮ずランダムアクセスは完党に盞互に排他的ではありたせん

ええ、適切な䜍眮に到達するためにオヌバヌヘッドを䌎う粗粒床のシヌクが必芁な堎合。 私はこのスペヌスでCRFSのstargzフォヌマットを䜿っおいく぀かの䜜業を

オヌバヌヘッドが十分に倧きいので、人々のために自動的にそれをしたくないのではないかず心配しおいたす。

けっこうだ。 重芁な問題は、倉曎が必芁な堎合、たたは実隓でオヌバヌヘッドが蚱容できるこずが瀺された堎合に、埌でこれに぀いお安䟡に考えを倉えるこずができるAPIを奜むかどうかです。

@bradfitzの良い点。 そしお、私は確かにそれを行うこずができたす。 FWIW、私のリポゞトリでは、.dファむルを衚瀺するずきの毒性が少なくなるようにgitも構成したした。 それでも、バッククォヌト付きの埋め蟌み文字列のプロパティは、予枬可胜であり、gitやシステムの気たぐれの圱響を受けないずいう点で䟿利だず思いたす。

コヌデックのアむデアで私が埗たのは、圧瞮だけが必芁な倉換ではなく、ナヌザヌが指定したコヌデックタむプを䜿甚するず、ツヌルチェヌンで「どのコヌデック」以倖のフラグを無芖できるずいうこずです。 圧瞮レベル、たたはアルゎリズムは、圧瞮たたはその他の方法で、䜿甚するコヌデックに固有である必芁がありたす。 私は、特定のフォヌマットずノブのセットを提䟛するずいう意味で「圧瞮をサポヌト」しようずするこずは、人々が求めるこずができるすべおのバリ゚ヌションを備えた野生のガチョりの远跡になるこずに完党に同意したす。 実際、i18nデヌタの前凊理や、 latlongのようなデヌタセットの凊理など、珍しい䜿甚法に最も興奮しおいるので、それでもその呚りのオプションを怜蚎する䟡倀があるず思いたす。

私は、より快適かもしれない同じ柔軟性を提䟛する別の方法を考えたした。 // go:embedディレクティブは、 // go:generateず同じように、コマンド呌び出しである可胜性がありたす。 最も単玔なケヌスでは、

// go:embed "file.name" go run example.com/embedders/cat file.name

䞻な違いは、もちろん、コマンド呌び出しのstdoutが指定された名前で埋め蟌たれおいるこずです。 この䟋では、 go runを含むふりパッケヌゞを䜿甚しお、コマンドOSを独立させる方法を瀺しおいたす。これは、Goがコンパむルするすべおの堎所でcat䜿甚できるずは限らないためです。

これにより、倉換の「゚ンコヌド」ステップが凊理され、「デコヌド」ステップのタスクはナヌザヌに任せるこずができたす。 ランタむム/埋め蟌みパッケヌゞは、゚ンコヌディングに関係なく、ナヌザヌがツヌルチェヌンに埋め蟌むように芁求したバむトを提䟛するだけです。 ナヌザヌはデコヌドプロセスがどうあるべきかを知っおいるので、これは問題ありたせん。

これの倧きな欠点の1぀は、埋め蟌たれたバむトがzipか䜕かである以倖に、この方法で耇数のファむルのグロブを埋め蟌む良い方法が芋圓たらないこずです。 グロブはzipコマンドで䜿甚できるので、実際にはそれで十分かもしれたせん。グロブを本圓に気にするのは定矩偎です。 しかし、この提案から2぀の機胜を䜿甚するこずもできたす。1぀は単玔な埋め蟌みを実行する機胜で、もう1぀はゞェネレヌタヌ埋め蟌みを実行する機胜です。

私に発生した可胜性のある欠点の1぀は、埋め蟌みがgo buildによっお凊理され、 go generateように远加のツヌルチェヌン呌び出しを必芁ずしないこずを前提ずしお、ビルドに自由圢匏のステップが远加されるこずです。 でも倧䞈倫だず思いたす。 おそらく、ツヌルは、コストのかかる操䜜の繰り返しを回避するために独自のキャッシュを管理するこずが期埅できたす。あるいは、ツヌルチェヌンず通信しおGoのキャッシュを䜿甚するこずもできたす。 それは解決できる問題のように聞こえ、 go buildが私たちのためにより倚くのこずをするずいう党䜓的なテヌマモゞュヌルのフェッチなどに適合したす。

このプロゞェクトの目暙の1぀は、Goビルドに倖郚ツヌルやgogenerate行が䞍芁であるこずを確認するこずですか

そうでない堎合は、物事をシンプルに保ち、バむトスラむスたたは文字列のみをサポヌトする䟡倀があるようです。ナヌザヌが倚数のノブで圧瞮したい堎合は、makeファむルたたは同様のもので圧瞮したり、ずにかくビルドする前に行を生成したりするこずができたす。したがっお、この提案の結果がどうなるかに関係なく、それらを远加する䟡倀はないようです。

Makeなどを必芁ずしないこずが目暙である堎合は、圧瞮を䜿甚するのが理にかなっおいるず思いたすが、個人的には、Makeや生成などを䜿甚しお圧瞮を行い、埋め蟌みを単玔にしお、いく぀かのバむトを埋め蟌むだけです。 。

@SamWhited 、

このプロゞェクトの目暙の1぀は、Goビルドに倖郚ツヌルやgogenerate行が䞍芁であるこずを確認するこずですか

はい。

gogenerate、Makefiles、たたはその他のツヌルを䜿甚したい堎合、今日では数十の遞択肢がありたす。

デフォルトで機胜する、ポヌタブルで安党で正しいものが必芁です。 明確にするために安党ずは、gogenerateがデフォルトで実行されないのず同じ理由で、「goinstall」時に任意のコヌドを実行できないこずを意味したす

@ stephens2424

埋め蟌みむンタラクションがオプションで「コヌデック」を提䟛できる堎合は、特定の圧瞮/倉換をアクティブにサポヌトする必芁があるツヌルチェヌンの必芁性を回避できるず思いたす。

go build䞭に任意のコヌドが実行されるこずはありたせん。

goビルド䞭に任意のコヌドが実行されるこずはありたせん。

ええ、私は今それを芋たす。 「゜ヌス」ファむルのみをリポゞトリにコミットし、「凊理枈み」ファむルを埋め蟌み、パッケヌゞを「取埗可胜」にし、 go buildシンプルか぀安党に保぀方法はないず思いたす。 私はただここで暙準化を掚進しおいたすが、私は自分のケヌキを持っおそれも食べたいず思っおいたず思いたす。 詊しおみる䟡倀 問題を芋぀けおくれおありがずう

@flimzy

これにより、リフレクションを介しお他の方法を䜿甚できなくなりたす。

私が述べたこずにはメ゜ッドはなく、関数だけです。 それらは実行時に発芋できず、゜ヌスで名前で蚀及せずにそれらを参照する方法はありたせん。 たた、異なる関数によっお返されるむンタヌフェむス倀は同じタむプである必芁はないこずに泚意しおください。実際、そのむンタヌフェむスを実装するために必芁なメ゜ッドを備えた非゚クスポヌトタむプか、 *strings.Readerむンスタンスのいずれかであるず予想されたす

ただし、間違いなく、このアむデアには、埋め蟌みパッケヌゞの゚クスポヌトされた関数を倀ずしお枡すずいう問題がありたす。 それでも問題にはならない可胜性がありたすが、眲名にぱクスポヌトされおいない型が含たれおいるため以䞋を参照、倉数、匕数、たたはそれらの型の戻り倀を宣蚀するこずはできたせん。 理論的には、それらをreflect.ValueOf自䜓に枡すこずができたす。 それで実際にそれらを呌び出すこずができるかどうかさえわかりたせん゚クスポヌトされおいないパラメヌタタむプの倀を䜜成する必芁がありたす。reflectで蚱可されおいる堎合はDunno。

ただし、次のようになりたす。 embed最䞊䜍関数が倀ずしお䜿甚され、すべおの埋め蟌みファむルに制限が生じる堎合に備えお、単玔に悲芳的になる可胜性がありたす最も単玔です。 ぀たり、embed-packageを䜿甚しお非垞に奇劙で圹に立たないこずを行うこずにした堎合、いく぀かの最適化が倱われたすずにかく、必ずしも玄束するわけではありたせん。 公平なようです。

実際、その圱響はそれよりも広いず思いたす。 FileReaderAtの䜿甚がデヌタを非圧瞮にする必芁があるこずを瀺しおいる堎合、非定数入力でFileReaderAtを䜿甚するず、すべおのファむルを非圧瞮で保存する必芁がありたす。

埋め蟌みを行うにはファむル名を静的に知る必芁があるため、非定数入力を蚱可するこずは意味がありたせん。 ただし、ファむル名パラメヌタヌのタむプずしおstringを䜿甚するのは䞍正確でした。これらは、実際にぱクスポヌトされおいないtype filename stringあり、関数の匕数ずしおのみ䜿甚されるべきでした。 そうすれば、型指定されおいない文字列定数以倖のものを枡すこずは䞍可胜です。

@Merovius

非定数入力を蚱可するこずは意味がありたせん

私たちはさたざたなこずに぀いお話しおいるず思いたす。 アクセサ関数ぞの入力぀たり、 FileReaderAt() を意味したす。ここでは、非定数入力が理にかなっおいるこずに同意するず思いたす。

そしお、私のポむントは次のずおりです。100個のファむルを埋め蟌んだものの、 FileReaderAt(filename)呌び出しがあり、 filenameは䞀定ではありたせん。 この方法でどの埋め蟌みファむルにアクセスするか実際に存圚する堎合を知る方法はないため、すべおを非圧瞮で保存する必芁がありたす。

@flimzy私たちは同じこずに぀いお話しおいたした、私は非constファむル名が意味をなさないず真剣に考えおいたせんでした:)それを考えるず、それは間違っおいお芋萜ずしでした。 申し蚳ありたせん。 ディレクトリ党䜓をグロブたたはむンクルヌドしおからそれらを反埩凊理する機胜は、実際には非垞に重芁です。 それでも、これは解決できるず思う-コレクションごずの意思決定をするこずにより、䟋えばDIR /グロブずのみ定数名によっおそれらを遞択するこずができたす-しかし、私は蚀ったようにそれは実際にAPI Iが原因のGOツヌルのためのスヌパヌ適切に怜蚎するではありたせんそれはなんお魔法なのでしょう。 したがっお、このように雑草に入るず、おそらく、抂念に倀するよりも倚くのスペヌスが議論に䞎えられたす:)

以前のメッセヌゞでは芋られず、ファむルをGoバむナリに埋め蟌むこずを怜蚎した別のケヌスは、通垞のgoビルド/むンストヌルを䜿甚しおC共有ラむブラリのラッパヌパッケヌゞを適切に配垃できないこずでした共有ラむブラリは゜ヌス。

私は結局それをしたせんでした、しかしそれは私がこの堎合のためにそれを再考するこずを間違いなくさせたす。 Cラむブラリには確かに倚くの䟝存関係があり、共有ラむブラリずしお配垃する方が簡単です。 この共有ラむブラリは、Goバむンディングによっお埋め蟌むこずができたす。

わお

@ゞュリオ-ゲラ
それらをディスクに抜出しおから、dlopenずdlsymを䜿甚しおC関数を呌び出す必芁があるず確信しおいたす。

線集あなたの投皿を少し誀解したした、あなたが配垃甚のバむナリを䜜成するこずに぀いお話しおいるこずに気づきたした

http静的アセットの倖郚で、メモリ内ぞのポむンタに必芁な埋め蟌みBLOBの堎合、すでに凊理䞭の埋め蟌みメモリぞのポむンタを返す関数があるず䟿利です。 そうしないず、新しいメモリを割り圓おお、io.Readerからコピヌを䜜成する必芁がありたす。 それは2倍のメモリを消費したす。

@glycerine 、繰り返したすが、それはstringです。 stringはポむンタず長さです。

コンパむル時に実行するコヌドにマヌクを付け、実行時に結果を提䟛する方法があるず䟿利ではないでしょうか。 そうすれば、任意のファむルを読み取っお、コンパむル時に必芁に応じお圧瞮し、実行時にアクセスするこずができたす。 これは、ファむルコンテンツのプリロヌドで機胜するため、䞀郚の蚈算では機胜したす。

スレッドで前に述べたように、 @ burkaは、 go buildは任意のコヌドを実行したせん。

@burka 、それは明らかに範囲倖です。 その決定コンパむル時にコヌドが実行されないはかなり前に行われたものであり、これはそのポリシヌを倉曎するためのバグではありたせん。

この提案の副䜜甚は、goプロキシが保存するファむルをgoファむルのみに最適化できないこずです。 プロキシは、GoコヌドにGo以倖のファむルが埋め蟌たれおいるかどうかがわからないため、リポゞトリ党䜓を保存する必芁がありたす。

プロキシがすでにこれを最適化しおいるかどうかはわかりたせんが、い぀かは実珟可胜になるかもしれたせん。

@leighmccullochでも、今日もそうは思わない。 Goパッケヌゞ内のGo以倖のファむルは、 go testで必芁になる可胜性があるため、モゞュヌルアヌカむブに含める必芁がありたす。 別の䟋ずしお、cgo甚のCファむルがある堎合もありたす。

これぱキサむティングな方向性であり、ナヌスケヌスには間違いなく必芁です。

ずはいえ、芁件が異なるさたざたなナヌスケヌスがあるように感じたすが、それを実行する必芁があるず考える_方法_に぀いおコメントしおいるほずんどの人は、暗黙的に独自のナヌスケヌスを想定しおいたすが、明瀺的に定矩しおいたせん。

ファむル埋め蟌み゜リュヌションのさたざたなナヌスケヌスず、各ナヌスケヌスが提瀺するできれば、圹立぀かもしれたせん—少なくずも私にずっおは本圓に圹に立ちたす—。

たずえば、私たちの䞻なナヌスケヌスは、HTML + CSS + JS + JPG + etcを埋め蟌んで、goアプリの実行時に、 http.FileServerで提䟛できるようにそれらのファむルをディレクトリに曞き蟌むこずができるようにするこずです。 。 Goからファむルにアクセスする必芁がないため、リヌダヌずラむタヌに぀いお私が読んだコメントのほずんどが私にずっお異質なナヌスケヌスであるこずを考えるず、 go-bindataそれらをディスクにコピヌさせるだけです_ただし怜蚎すべきこずにただ気付いおいない、より優れた手法を掻甚する方法があるかもしれたせん。_

ただし、課題は次のずおりです。通垞、デバッガヌでGoLandを䜿甚し、継続的な倉曎を行うWebアプリで䜜業したす。 したがっお、開発䞭に゜ヌスディレクトリから盎接ファむルをロヌドするにはhttp.FileServerが必芁です。 ただし、アプリの実行時に、 http.FileServerは、埋め蟌み゜リュヌションによっおファむルが曞き蟌たれたディレクトリからこれらのファむルを読み取る必芁がありたす。 ぀たり、コンパむルするずきに、go-bindataを実行しおファむルを曎新しおから、Gitにチェックむンする必芁がありたす。 そしお、それはすべお䞀般的にgo-bindataで実行可胜ですが、確かに考えられおいたせん。

ただし、コンパむルされた実行可胜ファむルを実際に実行する必芁がある堎合もありたす。そのため、実行䞭のプログラムにデバッガヌをアタッチしおも、埋め蟌みファむルがgo-bindataによっお曞き蟌たれるディレクトリからではなく、゜ヌスディレクトリからファむルをロヌドできたす。

これらが私たちのナヌスケヌスず課題です。 たぶん、他の人が他のナヌスケヌスず関連する䞀連の課題を明瀺的に定矩できるので、これらの議論はさたざたな問題空間に明瀺的に察凊でき、および/たたはこの取り組みが特定の問題空間の特定のニヌズに察凊しないこずを明瀺的に瀺すこずができたすか

よろしくお願いしたす。

ナヌスケヌスずしお蚀及されおいないので、template.ParseFilesを介しおアクセスするテンプレヌトのディレクトリにもこれが圹立ちたす。

最もクリヌンなアプロヌチは、 go.mod介しおオプトむンする方法だず思いたす。 これにより、䞋䜍互換性が確保され既存のプロゞェクトではオプトむンしお䜿甚する必芁があるため、ツヌルgoプロキシなどで必芁なファむルを刀別できたす。 go mod initコマンドを曎新しお、新しいプロゞェクトのデフォルトバヌゞョンを含め、将来䜿いやすくするこずができたす。

ディレクトリを暙準名にするオプトむンが必芁な堎合は、よりクリヌンでシンプルな名前にするこずができたす、たたはディレクトリの名前をgo.mod自䜓で定矩し、ナヌザヌが次のこずを行えるようにするための匕数を確認できたす。名前を遞択したすただし、デフォルトはgo mod init提䟛されたす。

私の考えでは、このような゜リュヌションは、䜿いやすさず「魔法」の枛少のバランスを実珟したす。

@jayconrodは曞いた

特別なディレクトリ名static /の代わりにコメントプラグマ// goembedを支持する1぀の匕数コメントを䜿甚するず、パッケヌゞたたはxtestアヌカむブのテストアヌカむブにファむルを埋め蟌むこずができたすが、ラむブラリは埋め蟌むこずができたせんテスト䞭。

これは本圓に玠晎らしい芳察です。 我々は特別なディレクトリ名を指定しお行きたいず思ったならば、我々はおなじみのメカニズムを䜿甚するこずができたすが staticすべおのビルドのために、 static_testテストビルドのために、 static_amd64 AMD64甚のビルド、およびすぐ。 ただし、任意のビルドタグサポヌトを提䟛する明確な方法はわかりたせん。

静的ディレクトリにマニフェストファむルが存圚する可胜性がありたす空のマニフェストが指定された堎合のデフォルトはマニフェスト以倖のすべおを含みたす。これにはグロブが含たれ、ビルドタグや埌で圧瞮などを指定できたす。

1぀の利点は、goリストがマニフェストを含むdirにヒットした堎合、そのツリヌをスキップできるこずです。

欠点の1぀は、非垞にhtaccesが発生する可胜性があり、感謝しないこずです。

ファむルをパッケヌゞにバンドルするための単玔なれロノブメカニズムは、パッケヌゞディレクトリ内の特別なディレクトリgo.files モゞュヌル内のgo.modず同様である可胜性がありたす。 シンボルの゚クスポヌトを遞択しない限り、アクセスはそのパッケヌゞに制限されたす。

線集単䞀機胜runtime/files提案

package files

func Open(name string) (io.ReadCloser, error) {
    // runtime opens embedded file based on caller package
    return rc, nil
}
package foo

import "runtime/files"

func ReadPackageFile(name string) ([]byte, error) {
    rc, err := files.Open(name)
    if err != nil {
        return nil, err
    }
    defer rc.Close()
    return ioutil.ReadAll(rc)
}

import "C"アプロヌチは、「魔法の」むンポヌトパスの先䟋をすでに蚭定しおいたす。 IMOそれはかなりうたくいきたした。

ナヌスケヌスずしお蚀及されおいないので、template.ParseFilesを介しおアクセスするテンプレヌトのディレクトリにもこれが圹立ちたす。

別の課題がありたす。バむナリには必芁なすべおのファむルが含たれおいる可胜性がありたすが、開発者が提䟛するデフォルトはそれらのファむルです。 ただし、むンプリントやプラむバシヌポリシヌなどのテンプレヌトは、゚ンドナヌザヌがカスタマむズできる必芁がありたす。 私が芋る限り、これは、デフォルトファむルを゚クスポヌトしお、実行時にバむナリにカスタマむズされたファむルを䜿甚させるか、埋め蟌みバヌゞョンをカスタマむズされたバヌゞョンに眮き換える方法が必芁であるこずを意味したす。

これは、埋め蟌みリ゜ヌスを「゚クスポヌト」および「眮換」する関数をAPIに提䟛するこずで実珟できるず思いたす。 次に、開発者ぱンドナヌザヌにいく぀かのコマンドラむンオプションを提䟛できたす前述のAPI呌び出しを内郚的に䜿甚したす。

もちろん、これはすべお、展開を確実に容易にする䜕らかの埋め蟌みが実際に存圚するずいう仮定に基づいおいたす。

問題を開いおいただきありがずうございたす。 仕事では、ほずんどすべおのGolangプロゞェクトにファむルを埋め蟌む必芁があるため、同じ機胜のアむデアに぀いお考えたした。 既存のラむブラリは正垞に機胜したすが、これはGolangが求めおいる機胜だず思いたす。 これは、単䞀の静的バむナリに倉換するために䜜成された蚀語です。 開発者に優しいナニバヌサルAPIを䜿甚しお、必芁なアセットファむルをバむナリにロヌドできるようにするこずで、それを受け入れる必芁がありたす。

奜みの実装の詳现をすばやく提䟛したいず思いたす。 耇数の人が、魔法のコメントのような別のシグナルを必芁ずする代わりに、埋め蟌みファむルを読み取るためのAPIを自動的に提䟛するこずに぀いお話したした。 アプロヌチに銎染みのあるプログラム的な構文を提䟛するので、それが進むべき道だず思いたす。 前述のように、おそらくruntime/embed特別なパッケヌゞを遞択するず、それが満たされ、将来的に簡単に拡匵できるようになりたす。 次のような実装は、私にずっお最も理にかなっおいたす。

type EmbedPackage interface {
    Bytes(filename string) []bytes
    BytesCompressed(filename string, config interface{}) []bytes // compressed in-binary as configured by some kind of config struct, memoizes decompression during runtime on first access
    Reader(filename string) io.Reader
    File(filename string) os.File // readonly and contains all metadata
    Dir(filepath string) []os.File 
    Glob(pattern string) []os.File // like filepath.Glob()

    // maybe? this could allow to load JSON, YAML, INI, TOML, etc files more easily
    // but would probably be too much for the std lib implementation
    Unmarshal(filename string, config interface{}, ptr interface{}) 
}

コヌドのどこかでそのパッケヌゞを䜿甚するず、コンパむラヌがトリガヌされ、ファむルが自動的に埋め蟌たれおランタむムに提䟛されたす。

// embed a file that is compressed in-binary and automatically decompressed on first access
var LongText = embed.BytesCompressed("legal.html", embed.Config{ Compression: "gzip", CompressionLevel: "9" })

// loads a single file as reader for easy access
var FewLinesOfText = bufio.NewReader(embed.Reader("lines.txt"))
for _, line := range FewLinesOfText.ReadLines() { ... }

// embeds all files in the directory
var PdfFontFiles = embed.Dir("/fonts")

// unmarshals file into custom config
var PdfProcessingConfig MyPdfProcessingConfig
embed.Unmarshal("/pdf_conversion.json", embed.Config{ Encoding: "text/json" }, &PdfProcessingConfig)

たた、go.modディレクトリの1぀䞋のディレクトリレベルたたはおそらく1぀䞋のディレクトリレベルのファむルぞのむンポヌトを制限すれば、セキュリティの問題ず再珟性は問題にならないはずです。これもスレッドですでに説明されおいたす。 絶察埋め蟌みパスは、そのdirectoyレベルに関連しお解決されたす。

コンパむルプロセス䞭にファむルにアクセスできないず、コンパむラ゚ラヌが発生したす。

バむナリの背埌にzipアヌカむブを䜜成するこずも可胜であるため、効果的に自己解凍型バむナリになるこずができたす。 たぶん、これはいく぀かのナヌスケヌスで圹立ちたすか ここで実隓ずしおこれを行いたした https 

Goにはすでに「testdata」がありたす。 ナニットテストでは、通垞のIOを䜿甚しお、やりたいこずをすべお実行したす。 テストスコヌプは、コンテンツが出荷されおいないこずを意味したす。 知っおおくべきこずはこれだけです。フリル、魔法、圧瞮されたコンテナロゞック、蚭定可胜なむンダむレクション、META-INFはありたせん。 矎しく、シンプルで、゚レガント。 バンドルされたランタむムスコヌプの䟝存関係甚の「デヌタ」フォルダヌがないのはなぜですか

Github eaの既存のGoプロゞェクトを簡単にスキャンしお、すでに「デヌタ」フォルダヌを䜿甚しおいるため、調敎が必芁なプロゞェクトをいく぀か思い぀くこずができたす。

私にははっきりしないもう䞀぀のこず。 staticディレクトリの議論に぀いおは、 static _source_ディレクトリに぀いお議論しおいるのか、ファむルが_atで利甚可胜になるstaticディレクトリに぀いお議論しおいるのかは100明確ではありたせん。 runtime_ 

たた、この区別は、開発プロセスず開発䞭のコヌドのデバッグに関連しおいるため、特に重芁です。

@mikeschinkel元の投皿から、ビルド時に埋め蟌みが行われるこずはかなり明らかです。

go install / go buildに埋め蟌みを自動的に行わせる

元の投皿ず䞊蚘のコメントの䞀郚では、実行時にファむルをロヌドするための「開発」モヌドに぀いおも説明しおいたす。

@mvdan回答ありがずうございたす。 ぀たり、提案された/static/ディレクトリは、アプリリポゞトリ、パッケヌゞリポゞトリ、たたはその䞡方のルヌトに盞察的であるず考えおいたすか

そしお、ランタむムファむルのその堎所は、開発者がそれらを配眮したい堎所に完党に䟝存したすか

それがすべお真実であり、論理的であるず思われる堎合は、デバッグ情報を䜿甚しおコンパむルされたプログラムが、オプションで゜ヌスの堎所からファむルをロヌドしお、倚くの远加の暙準化されおいないロゞックやコヌドなしでデバッグを容易にするこずができれば䟿利です。

䞊蚘の数人がモゞュヌルプロキシに぀いお蚀及したした。 これは、この機胜を適切に蚭蚈するための優れたリトマス詊隓だず思いたす。

今日では、ナヌザヌコヌドを実行せずに、ビルドで䜿甚されおいないファむルを削陀する実行可胜なモゞュヌルプロキシを実装するこずが可胜であるように思われたす。 䞊蚘の蚭蚈の䞀郚は、モゞュヌルプロキシがナヌザヌコヌドを実行しお、どの静的ファむルも含める必芁があるかを刀断する必芁があるこずを意味したす。

人々はたた、オプトむンずしおgo.modに぀いお蚀及したした。

アむデアgo.modファむルの仕様 他のツヌルが簡単に解析できるようにしたす。

module github.com/foo/bar

data internal/static ./static/*.tmpl.html

これにより、コンパむル時にファむルデヌタを䜿甚しおパッケヌゞが䜜成されたす。 ここではGlob構文が適しおいるかもしれたせんが、単玔化しおディレクトリを埋め蟌むだけで十分かもしれたせん。 䜙談ですが、 **グロブ構文の堎合は+1です。

import "github.com/foo/bar/internal/static"

f, err := static.Open("static/templates/foo.tmpl")

StripPrefixのようなものはここではいいかもしれたせんが、必須ではありたせん。 必芁なファむルパスを䜿甚するラッパヌパッケヌゞを簡単に䜜成できたす。

さらに簡略化できたす。

module github.com/foo/bar

data ./static/*.tmpl.html
import "runtime/moddata"

moddata.Open("static/foo.tmpl")

しかし、moddataが呌び出し元のパッケヌゞ/モゞュヌルに応じお異なる動䜜をするこずは少し盎感的ではありたせん。 ヘルパヌhttp.Filesystemコンバヌタヌなどを䜜成するのが難しくなりたす。

今日では、ナヌザヌコヌドを実行せずに、ビルドで䜿甚されおいないファむルを削陀する実行可胜なモゞュヌルプロキシを実装するこずが可胜であるように思われたす。 䞊蚘の蚭蚈の䞀郚は、モゞュヌルプロキシがナヌザヌコヌドを実行しお、どの静的ファむルも含める必芁があるかを刀断する必芁があるこずを意味したす。

ここで倧きな倉化はないず思いたす。 特に、Cコヌドにはすでにツリヌ内の任意のファむルが含たれおいる可胜性があるため、これを実行するモゞュヌルプロキシは、Cを解析する必芁がありたす。その時点で、導入する魔法のコメントやAPIは小さなステップになるようです。

䞊蚘の蚭蚈の䞀郚は、モゞュヌルプロキシがナヌザヌコヌドを実行しお、どの静的ファむルも含める必芁があるかを刀断する必芁があるこずを意味したす。

「goツヌルはビルド䞭にナヌザヌコヌドを実行しおはならない」ずいうのは、ここで亀差しない砂に描かれた線であるこずは明らかだず思いたす。 たた、goツヌルがナヌザヌコヌドを実行できない堎合は、それなしで含めるファむルを指定できる必芁がありたす。

私は、このナヌスケヌスに関するさたざたな考えを䜕か説埗力のあるものに凝瞮しようずしおきたした。そのため、 @ broadyが提案したものに倧きな+1をdataではなく動詞embedにする必芁があるず思いたす。

  1. 埋め蟌たれたファむルは、特別なコメントや魔法のパッケヌゞを持っおいるだけではなく、むンポヌトする必芁があるもののように感じたす。 たた、Goプロゞェクトでは、 go.modファむルは、開発者が必芁なモゞュヌル/ファむルを指定できる堎所であるため、埋め蟌みをサポヌトするように拡匵するこずは理にかなっおいたす。

  2. さらに、埋め蟌みファむルのコレクションは、1回限りの構文を䜿甚しおGoプロゞェクトにアドホックに远加するのではなく、パッケヌゞを含めるこずができれば、より䟡倀があり、再利甚できるように感じたす。 ここでの考え方は、埋め蟌みがパッケヌゞずしお実装されおいる堎合、人々はGithubを介しおそれらを開発および共有でき、他の人はプロゞェクトでそれらを䜿甚できるずいうこずです。 以䞋を含むGitHub䞊のコミュニティが管理する無料のパッケヌゞを想像しおみおください。

    NS。 各ファむルにその囜のすべおの郵䟿番号が含たれおいる囜のファむル、
    NS。 ブラりザを識別するためのすべおの既知のナヌザヌ゚ヌゞェント文字列を含むファむル、
    NS。 䞖界各囜の旗の画像、
    NS。 Goプログラムで䞀般的に発生する゚ラヌを説明する詳现なヘルプ情報、
    e。 等々...

  3. goembed://などの新しいURLスキヌムたたは既存のスキヌムを䜿甚しお、パッケヌゞからファむルを開いたり読み取ったりできるため、新しいファむルを䜜成する代わりに、_すべお_の既存のファむル操䜜APIを掻甚できたす。珟圚のパッケヌゞに含たれおいる埋め蟌みに関連する次のようなもの

    data, err := ioutil.ReadFile("goembed://postal-codes.txt")    
    if (err != nil) {
      fmt.Println(err)
    }
    

䞊蚘の抂念では、_ "魔法" _のように感じるものはありたせん。 すべおが目的のために意図されたように感じるメカニズムによっお゚レガントに凊理されたす。 必芁な拡匵はほずんどありたせん。 go.mod 1぀の新しい動詞ず、Goによっお内郚的に認識される1぀の新しいURLスキヌム。 それ以倖はすべお、Goからそのたた提䟛されたす。

私が今しおいるこず

私は今これにcode.soquee.net/pkgzipを䜿甚しおいたすグロヌバルな状態ずむンポヌトの副䜜甚を回避するためにAPIを倉曎するのはstatikフォヌクです。 私の通垞のワヌクフロヌ少なくずもWebアプリではは、ZIPファむルにバンドルされたアセットを埋め蟌み、 golang.org/x/tools/godoc/vfs/zipfsずgolang.org/x/tools/godoc/vfs/httpfsを䜿甚しおそれらを提䟛するこずです。

goembedアプロヌチ

私がgo:embedアプロヌチを採甚するこずをおそらく劚げる2぀のこずがありたす

  1. 生成されたコヌドはドキュメントに衚瀺されたせん
  2. アセットはコヌドベヌス党䜓に散圚しおいる可胜性がありたすこれは倖郚ツヌルずgo:generateを䜿甚する堎合にも圓おはたりたす。そのため、通垞、ビルドする前にmakefileを䜿甚しおさたざたなアセットのセットを生成するこずを奜みたす。それらすべおをmakefileで芋るこずができたす

アセットをモゞュヌル党䜓ではなくパッケヌゞの䞀郚にするこずは、ビルドタグ、パッケヌゞのテストなどのすべおの耇雑さを意味するずいう䞀郚の機胜である可胜性があるため、䞊蚘に含めない問題もありたす。 。それらに適甚する堎合、それらがそのパッケヌゞに察しおパブリックであるかプラむベヌトであるかを指定する方法などが必芁です。これは、ビルドが非垞に耇雑になるようです。

私が気に入っおいるのは、アセットのむンポヌトを簡単にするラむブラリを䜜成できるこずです。 䟋えば。 フォントを埋め蟌むだけの単䞀のGoファむルを含むラむブラリ、たたはいく぀かのアむコンを公開しお、他のGoパッケヌゞず同じようにむンポヌトするこずができたす。 将来的には、むンポヌトするだけでアむコンフォントを取埗できるようになりたす。

import "forkaweso.me/forkawesome/v2"

埋め蟌みパッケヌゞアプロヌチ

これをすべお明瀺的で通垞のGoコヌドにするずいうアむデアは奜きですが、これが暙準ラむブラリの倖郚では実装できない別の魔法のパッケヌゞになるずいうアむデアは嫌いです。

そのようなパッケヌゞは蚀語仕様の䞀郚ずしお定矩されたすか そうでなければ、Goコヌドが異なる実装間で壊れおしたう別の堎所であり、これもたた貧匱な感じがしたす。 この砎損を防ぐために、倖郚ツヌルを䜿い続けるず思いたす。

たた、他の人が蚀及しおいるように、これがビルド時に行われおいるずいう事実は、このパッケヌゞが匕数ずしお文字列リテラルたたは定数のみを取るこずができるこずを意味したす。 珟圚、型システムでこれを衚珟する方法はなく、混乱のポむントになるず思いたす。 これは定数関数のようなものを導入するこずで解決できたすが、今は䞻芁な蚀語の倉曎に぀いお話しおいるので、初心者ではありたせん。 そうでなければ、これを修正する良い方法がわかりたせん。

ハむブリッド

私はハむブリッドアプロヌチのアむデアが奜きです。 コメントを再利甚する代わりに最終的にはあちこちに散らばり、個人的なメモでは、ただグロスに感じたす、すべおのアセットを1぀の堎所に配眮し、おそらくgo.modファむルを他のアセットず同じように衚瀺したいず思いたす。蚀った

module forkaweso.me/forkawesome/v2

go 1.15

embed (
    fonts/forkawesome-webfont.ttf
    fonts/forkawesome-webfont.woff2
)

぀たり、アセットは、個別のモゞュヌルを䜜成せずに、任意のビルドタグ、たたは任意のパッケヌゞ_testingパッケヌゞなどに含めたり陀倖したりするこずはできたせん。 この耇雑さの軜枛が望たしいず思いたすむンポヌトしようずしおいるラむブラリにビルドタグが隠されおおらず、ラむブラリをむンポヌトするずアセットが埋め蟌たれおいるはずなので、適切なアセットがない理由がわかりたせん 、しかしYMMV。 これが望たしい堎合は、コヌドを生成せず、代わりにgo.modバヌゞョンに぀いお説明するのず同じアプロヌチを䜿甚するこずを陀いお、コメントのようなプラグマを䜿甚できたす。

圓初の提案ずは異なり、これは任意のコヌドを生成したせん。 代わりに、䟋えばの機胜。 ELFファむルのデヌタセクションの読み取りたたは、䜿甚しおいるOSに保存されるこずになりたすは、必芁に応じお远加されたすたずえば、 osたたはdebug/elfなど。次に、オプションで、OPで説明されおいるパッケヌゞずたったく同じように動䜜する新しいパッケヌゞが䜜成されたすが、魔法のように埋め蟌たれるのではなく、埋め蟌たれたファむルを読み取るだけです぀たり、暙準ラむブラリの倖郚で実装できたす。必芁に応じお。

これは、匕数ずしお文字列リテラルのみを蚱可するようにマゞックパッケヌゞを制限する必芁があるなどの問題を回避したすが、埋め蟌みアセットが実際にどこかで䜿甚されおいるかどうか、たたは最終的に自重であるかどうかを確認するのが難しいこずを意味したす。 たた、䜙分なものをむンポヌトする必芁がある唯䞀のパッケヌゞは新しいパッケヌゞ自䜓であるため、暙準ラむブラリパッケヌゞ間の新しい䟝存関係を回避したす。

var IconFont = embed.Dir("forkaweso.me/forkawesome/v2/fonts/")
var Logo = embed.File("images/logo.jpg")

䞊で芋たように、モゞュヌルにリ゜ヌスを配眮するこずで、必芁に応じおその特定のモゞュヌルにリ゜ヌスをスコヌプするこずができたす。 実際のAPIずアセットの遞択方法には、いく぀かの䜜業が必芁になる堎合がありたす。

さらに別のアむデア go.modに新しい皮類の動詞embedを远加する代わりに、新しい皮類のパッケヌゞであるデヌタパッケヌゞを導入しお、go.modでむンポヌトしお䜿甚するこずができたす。通垞の方法。 これがストロヌマンのスケッチです。

パッケヌゞに.goファむルstatic.goだけ含たれおいお、そのファむルにコメントずパッケヌゞ句のみが含たれおいる堎合、パッケヌゞはデヌタパッケヌゞです。 むンポヌトされるず、cmd / goは、結果のバむナリに埋め蟌たれおいるファむルぞのアクセスを提䟛する゚クスポヌトされた関数をパッケヌゞに入力したす。

それが実際のパッケヌゞである堎合、それはinternalルヌルが適甚され、APIに远加せずにアクセス制埡を持぀こずができるこずを意味したす。

.go以倖のすべおのファむルずサブフォルダヌ実際のコヌドルヌルがない堎合をディレクトリに自動的に含めるのはどうですか

パッケヌゞに.goファむルstatic.goだけ含たれおいお、そのファむルにコメントずパッケヌゞ句のみが含たれおいる堎合、パッケヌゞはデヌタパッケヌゞです。

このチェックは、ビルドタグを適甚する前に実行されたすか もしそうなら、それは避けたいかもしれないさらに別の特別な堎合のようです。 そうでない堎合、パッケヌゞが䞀郚のビルドタグの暙準のGoパッケヌゞず芋なされ、他のビルドタグのデヌタパッケヌゞず芋なされる可胜性がありたす。 それは奇劙に思えたすが、倚分それは望たしいですか

@flimzy
これにより、1぀のタグで埋め蟌みファむルを䜿甚し、生成されたパッケヌゞず同じfns / varsを定矩し、別のタグでファむルを別の方法おそらくリモヌトで提䟛できるようになりたす。

ラッパヌ関数を生成するためのビルドフラグがあれば、空癜を埋めるだけでよいでしょう。

@josharian

パッケヌゞに.goファむルstatic.goだけ含たれおいお、そのファむルにコメントずパッケヌゞ句のみが含たれおいる堎合、パッケヌゞはデヌタパッケヌゞです。

「デヌタ」パッケヌゞは、郵䟿番号怜玢など、独自のドメむン固有の機胜を備えおいるず想像できたす。 先ほど提案したアプロヌチでは、生デヌタ以倖のものは蚱可されないため、ロゞックをデヌタずパッケヌゞ化できるずいう利点は無効になりたす。

「デヌタ」パッケヌゞは、郵䟿番号怜玢など、独自のドメむン固有の機胜を備えおいるず想像できたす。

my.pkg / postalcodeで機胜を公開し、my.pkg / postalcode / dataたたはmy.pkg / postalcode / internal / dataにデヌタを配眮できたす。

あなたが提案する方法でそれを行うこずの魅力はわかりたすが、それは倚くの疑問を提起したす埌方互換性はどのように機胜したすか デヌタパッケヌゞをそのようにマヌクするにはどうすればよいですか パッケヌゞにcmd / goが远加する機胜ず競合する機胜がある堎合はどうしたすか 私はこれらに答えがないず蚀っおいるのではなく、答える必芁がない方が簡単だずいうだけです。

@josharian 、䞊蚘のタむプチェックコメントhttps://github.com/golang/go/issues/35950#issuecomment-561443566を怜蚎しおください。

@bradfitzはい、これは蚀語の倉曎であり、go / typesのサポヌトが必芁になりたす。

実際には、蚀語を倉曎せずにこれを行う方法がありたす。static.goには、cmd / goが入力する内容ず完党に䞀臎するボディレス関数が含たれおいる必芁がありたす。

static.goに、cmd / goが入力する内容ず完党に䞀臎するボディレス関数を含める必芁がありたす。

すべおのembed.File()キャッチするのではなく、ファむルごずの関数を生成する堎合は、アセットごずの゚クスポヌト制埡が簡単になりたす。

したがっお、生成されたものは次のようになりたす。

EmbededFoo() embed.Asset {...}
embededBar() embed.Asset {...}

4か月前に静的ファむルに぀いお曞いたブログ投皿。 結論の最埌の文を参照しおください:-)

@josharian

my.pkg / postalcodeで機胜を公開し、my.pkg / postalcode / dataたたはmy.pkg / postalcode / internal / dataにデヌタを配眮できたす。

それは—゚レガントではありたせんが—私の懞念に察凊するこずができたす。

䞋䜍互換性はどのように機胜したすか

ここでは、BCの懞念がどのように圓おはたるのかわかりたせん。 詳现を教えおいただけたすか

デヌタパッケヌゞをそのようにマヌクするにはどうすればよいですか

embedで声明go.mod 

倚分私はあなたが求めおいるこずに埓わないでしょう。

しかし、私はそれを奜転させたす。 デヌタのみでパッケヌゞをマヌクするにはどうすればよいですか

パッケヌゞにcmd / goが远加する機胜ず競合する機胜がある堎合はどうしたすか

  1. 提案されたアプロヌチを䜿甚するず、これらの機胜を远加するためにcmd / goが必芁になるずは思いたせん。

  2. cmd / goで関数を远加する必芁がある堎合でも、_existing_パッケヌゞでの競合の動䜜は_undefined_になるず思いたす。

    この提案は、開発者が単䞀責任の原則に埓うこずを前提ずしおいるため、デヌタを含むパッケヌゞをデヌタ䞭心のパッケヌゞずしおのみ構築し、既存のロゞック䞭心のパッケヌゞにデヌタを远加しないようにする必芁がありたす。

    もちろん、開発者は既存のパッケヌゞに远加するこずができたす。その堎合、動䜜は未定矩になりたす。 IOW、開発者がむディオムを無芖した堎合、圌らは未知の領域にいるでしょう。

私はこれらに答えがないず蚀っおいるのではなく、答える必芁がない方が簡単だずいうだけです。

答えは簡単だず思うこずを陀いお。 少なくずもあなたがこれたでに提起したものに぀いおは。

シンボルたたはシンボルの倀を远加する゜リュヌションは、モゞュヌルスコヌプではなくパッケヌゞスコヌプでなければならないず思いたす。 Goのコンパむル単䜍はパッケヌゞであり、モゞュヌルではないためです。

したがっお、これにより、むンポヌトするファむルのリストを指定するためのgo.mod䜿甚が陀倖されたす。

@dolmen最終結果が独自のパッケヌゞに含たれる堎合、スコヌプ自䜓はモゞュヌルになりたす。

@urandomいいえ、スコヌプは、生成されたパッケヌゞをむンポヌトするパッケヌゞです。 しかしずにかく、完党に生成されたパッケヌゞがこの提案の範囲に含たれるずは思いたせん。

@urandomいいえ、スコヌプは、生成されたパッケヌゞをむンポヌトするパッケヌゞです。 しかしずにかく、完党に生成されたパッケヌゞがこの提案の範囲に含たれるずは思いたせん。

この提案がどのように実装されるかに関係なく、さたざたなモゞュヌルパッケヌゞが最終結果を䜿甚するこずを考えるず、埋め蟌たれるものの定矩がモゞュヌルレベルで指定されるこずは理にかなっおいたす。 これの前䟋は、埋め蟌みファむルがモゞュヌルスコヌプでマゞックディレクトリから远加されるJava゚コシステムにもすでに存圚したす。

さらに、go.modは、既存のプログラムを壊すこずなく、そのような機胜魔法のコメントや魔法のディレクトリなしを远加するための最もクリヌンな方法を提䟛したす。

ただ蚀及されおいないこずがありたす。Go゜ヌス凊理ツヌルコンパむラヌ、静的アナラむザヌのAPIは、ランタむムAPIず同じくらい重芁です。 この皮のAPIは、゚コシステムの成長に圹立぀Goのコアバリュヌです go/ast / go/formatやgo mod edit 。

このAPIは、プリプロセッサツヌル特にgo:generateステップで䜿甚しお、埋め蟌たれるファむルのリストを取埗したり、参照を生成したりするこずができたす。

特別なパッケヌゞの堎合、 go.mod解析 go modツヌルたたはgo/astパヌサヌで倉曎するものは䜕もありたせん。

@ドルメン

_ "シンボルたたはシンボルの倀を远加する゜リュヌションは、モゞュヌルスコヌプではなくパッケヌゞスコヌプである必芁があるず思いたす。Goのコンパむルナニットはモゞュヌルではなくパッケヌゞであるため、go.modを䜿甚しおのリストを指定する必芁はありたせん。むンポヌトするファむル。 "_

モゞュヌルずは䜕ですか モゞュヌルは_ "単䞀のナニットずしお䞀緒にバヌゞョン管理される関連するGoパッケヌゞのコレクションです。" _したがっお、モゞュヌルは単䞀のパッケヌゞで構成でき、単䞀のパッケヌゞはモゞュヌル党䜓である可胜性がありたす。

そのため、Goチヌムが特別なコメントや魔法のパッケヌゞよりもgo.modを採甚しおいるず仮定するず、 go.modはむンポヌトするファむルのリストを指定する正しい堎所です。 それは、Goチヌムがgo.pkgファむルを远加するこずを決定しない限りです。

さらに、Goチヌムが埋め蟌みファむルを指定する堎所ずしおgo.modを受け入れる堎合、ファむルを埋め蟌みたい人は、 embed説明ずパッケヌゞをgo.mod提䟛する必芁がありたす。 go.modファむルが存圚するディレクトリで衚されるものは、埋め蟌みファむルを含むパッケヌゞになりたす。

しかし、それが開発者の望みではない堎合は、別のgo.modファむルを䜜成し、埋め蟌みファむルを含めるパッケヌゞのディレクトリに配眮する必芁がありたす。

これらの制玄が機胜しないず想定する正圓なシナリオはありたすか

@mikeschinkel 、モゞュヌルは_related_パッケヌゞのコレクションです。 ただし、モゞュヌル内の他のパッケヌゞの掚移的な䟝存関係およびデヌタを取埗せずに、モゞュヌルから1぀のパッケヌゞを䜿甚するこずは可胜ですそしお合理的です。

デヌタファむルは通垞、モゞュヌルごずではなくパッケヌゞごずの䟝存関係であるため、これらの䟝存関係を芋぀ける方法に関する情報は、個別のモゞュヌルレベルのメタデヌタずしお保存するのではなく、パッケヌゞず同じ堎所に配眮する必芁がありたす。

@bcmills

メッセヌゞ内の「デヌタファむル」を「モゞュヌル」に眮き換えるこずができるようですが、それでも圓おはたりたす。
独自の特定のパッケヌゞの䟝存関係ずしお特定のモゞュヌルを持぀こずは非垞に䞀般的です。
それでも、それらすべおをgo.mod内に配眮したす。

@urandom 、 go.modファむルに瀺されおいるモゞュヌル内のすべおのパッケヌゞが最終的なバむナリにリンクされおいるわけではありたせん。  go.modファむルに䟝存関係を眮くこずは、その䟝存関係をプログラムにリンクするこずずは_等しくありたせん_。

メタポむント

これが倚くの人々が気にかけおいるこずであるこずは明らかであり、䞊郚のブラッドの元のコメントは、最初のスケッチ/開始点/行動の呌びかけよりも完成した提案ではありたせんでした。 この時点で、この特定の議論を終わらせ、ブラッドずおそらく他の数人が詳现な蚭蚈ドキュメントで共同䜜業を行い、その特定のただ曞かれおいないドキュメントの議論のために新しい問題を開始するこずは理にかなっおいるず思いたす。 それは、少し広倧な䌚話になっおいるこずに集䞭するのに圹立぀ようです。

考え

これを閉じるこずに同意するかどうかはわかりたせんが、提案は可胜です-蚭蚈ドキュメントが䜜成されるたで保留し、コメントを少しロックしたす。 コメントが冗長であるかどうかを確認するにはコメントが倚すぎるため、この時点ではほずんどすべおのコメントが冗長です...

たぶん、デザむンドキュメントがあるずきは、これを閉じるこずができたす。

たたは、これを閉じお3035を再床開きコメントを凍結しお、少なくずも1぀の未解決の問題がそれを远跡するようにしたす。

クロヌゞングに぀いお話し合った盎埌にこれを行っお申し蚳ありたせんが、 @ bcmillsのコメントの盎埌で、明確にする前に、クロヌズの議論が

"_ただし、モゞュヌル内の他のパッケヌゞの掚移的な䟝存関係およびデヌタを取埗せずに、モゞュヌルから1぀のパッケヌゞを䜿甚するこずは可胜ですそしお合理的です。" _

はい、明らかにそれは_可胜です。_しかし、他のベストプラクティスず同様に、デヌタパッケヌゞのベストプラクティスは、モゞュヌル甚の単䞀のパッケヌゞを䜜成するこずであり、これにより懞念が解決されたす。 それがルヌトにgo.modを意味し、デヌタパッケヌゞを含むサブディレクトリに別のgo.modを意味する堎合は、そうです。

私はあなたがここで善の敵になるこずを完璧にしないこずを䞻匵しおいるず思いたす。ここで善はgo.modずしお識別され、埋め蟌みファむルを指定するのに最適な堎所です。モゞュヌルのコンポヌネント。

申し蚳ありたせんが、パッケヌゞはGoの基本的な抂念であり、モゞュヌルではありたせん。
モゞュヌルは、1぀のナニットずしおバヌゞョン管理されるパッケヌゞの単なるグルヌプです。
モゞュヌルは、個々のパッケヌゞのセマンティクス以倖に远加のセマンティクスを提䟛したせん。
それは圌らの単玔さの䞀郚です。
ここで行うこずはすべお、モゞュヌルではなくパッケヌゞに関連付ける必芁がありたす。

これがどこに行っおも、それがどのように行われたずしおも、䜿甚されおいるパタヌンだけでなくgolistを䜿甚しお埋め蟌たれるすべおのアセットのリストを取埗する方法があるはずです。

ブラッドず他の人が正匏な蚭蚈ドキュメントを䜜成するたで保留にしたす。

特にstaticたたはembedディレクトリを䜿甚しおいる堎合は、特定のファむルをブロックするのはそれほど難しくありたせん。 シンボリックリンクはそれを少し耇雑にするかもしれたせんが、珟圚のモゞュヌルの倖郚、たたはGOPATHを䜿甚しおいる堎合は、ディレクトリを含むパッケヌゞの倖郚に䜕かが埋め蟌たれないようにするこずができたす。

私はコヌドにコンパむルされるコメントのファンではありたせんが、コンパむルに圱響を䞎える疑䌌パッケヌゞも少し奇劙だず思いたす。 ディレクトリアプロヌチを䜿甚しない堎合は、ある皮のembedトップレベル宣蚀を実際に蚀語に組み蟌む方が少し理にかなっおいるかもしれたせん。 importず同様に機胜したすが、ロヌカルパスのみをサポヌトし、割り圓おるための名前が必芁になりたす。 䟋えば、

embed ui "./ui/build"

func main() {
  file, err := ui.Open("version.txt")
  if err != nil {
    panic(err)
  }
  version, err = ioutil.ReadAll(file)
  if err != nil {
    panic(err)
  }
  file.Close()

  log.Printf("UI Version: %s\n", bytes.TrimSpace(version))
  http.ListenAndServe(":8080", http.EmbeddedDir(ui))
}

線集あなたはそれに私を打ち負かしたした、@ jayconrod。

これはクリヌンで読みやすいですが、goチヌムが新しいキヌワヌドを導入したいかどうかはわかりたせん

私が芚えおいるアむデアは、静的デヌタを含む「static」のような特別なディレクトリ名を蚭定し、泚釈を必芁ずせずにAPIを介しお自動的に利甚できるようにするこずでした。

特別なディレクトリ名ずしおstaticを䜿甚するのは少し混乱するので、 assetsを䜿甚したいず思いたす。
スレッドで芋なかったもう1぀のアむデアは、 assetsをパッケヌゞずしおむンポヌトできるようにするこずです䟋 import "example.com/internal/assets" 。 公開されたAPIにはただデザむンが必芁ですが、少なくずも特別なコメントや新しいruntime/filesスタむルのパッケヌゞよりもきれいに芋えたす。

スレッドで芋なかったもう1぀のアむデアは、アセットをパッケヌゞずしおむンポヌトできるようにするこずです。

これはここで提案されたした https 

耇雑な点の1぀は、タむプチェックを有効にするには、これを蚀語の倉曎にするか、cmd / goで入力する本文のない関数を提䟛する必芁がある

これも同様のアむデアですが、 static.go蚭蚈では、任意のむンポヌトパスをデヌタパッケヌゞに倉換できたすが、 assetsディレクトリはtestdata 、 internalたたはvendor 「特別」であるずいう点でassetsが持぀可胜性のある芁件の1぀は、Goパッケヌゞを含たないたたはドキュメントのみを蚱可するこずです。぀たり、暗黙的な䞋䜍互換性のためです。

これは、ファむルを取埗するためのruntime/files -thingyAPIず組み合わせるこずもできたす。 ぀たり、生のimportを䜿甚しおディレクトリツリヌにファむルを埋め蟌み、ランタむムパッケヌゞを䜿甚しおそれらにアクセスしたす。 os.Openでさえあり埗たすが、それが受け入れられる可胜性は䜎いです。

shurcooL/vfsgen合わせおshurcooL/httpgzipは、解凍せずにコンテンツを提䟛できる優れた機胜がありたす。

䟋えば

    rsp.Header().Set("Content-Type", "image/png")
    httpgzip.ServeContent(rsp, req, "", time.Time{}, file)

同様の機胜がC ++甚に提案されおいたす std::embed 

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r0.html
https://mobile.twitter.com/Cor3ntin/status/1208389050698215427

デザむンのむンスピレヌションずしお、たた考えられるナヌスケヌスを収集するのに圹立぀堎合がありたす。

私はパヌティヌに少し遅れおいたすが、私は考えを持っおいたした。 特別なコメントの代わりに、固定された特別なディレクトリ静的、たたはgo.modを拡匵するための明らかにノヌノヌのアプロヌチパッケヌゞごずの新しいマニフェストファむルはどうですかgo.res

  • ファむルのリストが含たれおいたす。 パスやグロブはなく、珟圚のパッケヌゞディレクトリ内の名前だけです。 必芁に応じお、コミットする前にglobから生成したす。

    • __Edit__ goファむルのように、䞊郚にpackage mypackagename行のpackageヘッダヌ行の方が奜きです。

  • 「resource」たたは「io / resource」ず呌ばれる新しいコアパッケヌゞ。 珟圚のパッケヌゞに埋め蟌たれおいるリ゜ヌスを読み取るためのfunc Read(name string) (io.Reader, bool)関数が少なくずも1぀ありたす。

    • __線集__コアパッケヌゞがこのように機胜するかどうかわからない。 生成されたパッケヌゞプラむベヌト関数である必芁がある堎合がありたす䟋 func readresource(name string) (io.Reader, bool) 

  • サブディレクトリにリ゜ヌスが必芁な堎合は、go.resファむルず少なくずも1぀の.goファむルを远加しお、サブディレクトリをパッケヌゞにしたす。 goファむルは、サブディレクトリパッケヌゞ内のリ゜ヌスにアクセスするための独自のパブリックAPIを゚クスポヌトしたす。 他のパッケヌゞのリ゜ヌスは蚭蚈䞊自動的に゚クスポヌトされないため、goファむルず゚クスポヌトされたAPIが必芁です。 この方法で゚クスポヌトする方法をカスタマむズするこずもできたす。

    • __Edit__たたは、ディレクトリ構造や圧瞮が必芁な堎合は、tarリ゜ヌスを䜿甚したす。 これにより、すでにコンパむルが必芁なそしお、事前圧瞮の恩恵を受ける可胜性があるwebpackバンドルのようなものが可胜になりたす。 それらをtarに䞀歩進めるのは簡単です。

  • __線集__マニフェストが必芁ですか go.resファむル自䜓をリ゜ヌスずしお含めるだけです。 listresources関数を䜜成する必芁はありたせん。

非垞にシンプルです。 1぀の新しい機胜。 1぀の新しいファむル。 パスはありたせん。 圧瞮なし。 新しい構文はありたせん。 魔法はありたせん。 拡匵可胜。 リヌダヌを介した読み取り専甚アクセスただし、将来的には別のアクセスパタヌンを利甚できるようになりたす。 既存のパッケヌゞを壊す可胜性はほがれロです。 パッケヌゞがgoのコアコンストラクトであるこずを維持したす。

__Edit__ githubでlanguage:go filename:go.res extension:res怜玢した埌、 go.resを䜿甚するのはかなり安党なファむル名のようです。 goリポゞトリには䞀臎するものはなく、非goリポゞトリにはわずかしか䞀臎したせん。

@ chris.ackermanmのアむデアが奜きです。 しかし、私は組み合わせを奜むでしょう

ディレクトリ内の名前空間を指定するgo.resファむル。

これにより、

  • 名前空間が異なる限り、耇数のむンクルヌド
  • 以前にファむルを知らず、リストを生成する必芁がある

埌者は、曎新やさたざたなオプションなどによっおレむアりトが倉曎される可胜性のあるwebpackなどの出力に取り組む必芁がありたす。

圧瞮に関しおバむナリサむズが爆発しないずいう点で、より倚くの機胜であり、䜿甚するコヌドに察しお透過的である必芁があるず思いたす。

埌で、次のような曞き換えを蚱可できたす。

filename => stored-as.png

ちょうど私の2¢

@ sascha-andres非垞にシンプルで、魔法がれロのようです。このスレッドのトヌンです。 私がコメントに察しお行った線集を参照しおください。

マッピングが奜きではありたせん。 必芁なし。 ずにかく別のパッケヌゞから独自の読み取り関数を公開するこずでそれが可胜になり、新しいファむル構文、たたは1行あたりのファむルよりも耇雑なものが必芁になりたす。

やあ

この提案は玠晎らしいです

そしお、私は、emebed資産ぞの私のアプロヌチを持っおいたす。 GNUbintools以倖のツヌルを導入する必芁はありたせん。 ちょっず汚いですが、今のずころうたくいきたす。 私はそれを共有しお、それが圹立぀かどうかを確認したいず思いたす。

私のアプロヌチは、アセットtargzで圧瞮をobjcopyを䜿甚しおelf / pe32セクションに埋め蟌み、必芁に応じおzipずずもにパッケヌゞdebug / elfおよびdebug / pe32を介しお読み取るこずです。 私が芚えおおく必芁があるのは、既存のセクションに觊れないこずだけです。 すべおのアセットは䞍倉であり、コヌドはコンテンツを読み取り、メモリ内で凊理したす。

私は蚀語蚭蚈やコンパむラ蚭蚈にかなり䞍慣れです。 したがっお、䞊蚘のアプロヌチを䜿甚し、セクション名ずしお.goassetsなどを䜿甚したす。 圧瞮をオプションにしたす。

私のアプロヌチは、アセットtargzで圧瞮をobjcopyを䜿甚しおelf / pe32セクションに埋め蟌み、必芁に応じおzipずずもにパッケヌゞdebug / elfおよびdebug / pe32を介しお読み取るこずです。 私が芚えおおく必芁があるのは、既存のセクションに觊れないこずだけです。 すべおのアセットは䞍倉であり、コヌドはコンテンツを読み取り、メモリ内で凊理したす。

elf / pe32で動䜜するように聞こえたすが、 mach-o / plan9どうですか

もう1぀の問題は、実行可胜ファむルのファむルハンドルを開くこずに䟝存しおいるこずです。実行可胜ファむルが䞊曞き/曎新/削陀された堎合、これは異なるデヌタを返したすが、それが正圓な問題なのか予期しない機胜なのかはわかりたせん。

私は debug / machoを䜿甚しお少しmach-o-x86-64を砎損しおいるようです。 mach-o構造を理解しおいないだけで、 objcopy芋たので長すぎる可胜性がありたす。

もう1぀の問題は、実行可胜ファむルのファむルハンドルを開くこずに䟝存しおいるこずです。

プログラムロヌダヌがリ゜ヌスセクションをメモリにロヌドするたたはロヌドできるず確信しおいるので、デバッグパッケヌゞを䜿甚する必芁はありたせん。 ただし、デヌタにアクセスするには、オブゞェクトファむルをいじくり回す必芁がありたす。

䜕が機胜するか、たずえばJavaがどのように機胜するかに埓っおみたせんか。 私は物事を倧げさなものにする必芁がありたすが、次のようなものがありたす。

  • go.resファむルを䜜成するか、 go.modを倉曎しお、リ゜ヌスがあるディレクトリを指すようにしたす。
  • このディレクトリのすべおのファむルは自動的に含たれ、コンパむラによる䟋倖は最終的な実行可胜ファむルに含たれ
  • 蚀語は、これらのリ゜ヌスにアクセスするためのパスのようなAPIを提䟛したす

圧瞮などは、このリ゜ヌスバンドルの範囲倖である必芁があり、必芁に応じお// go:generateスクリプトたで可胜です。

誰かがmarkbates / pkgerを芋たこずがありたすか これは、珟圚の䜜業ディレクトリずしおgo.modを䜿甚する非垞に単玔な゜リュヌションです。 index.htmlが埋め蟌たれるず仮定するず、それを開くずpkger.Open("/index.html")たす。 これは、プロゞェクトでstatic/ディレクトリをハヌドコヌディングするよりも良い考えだず思いたす。

たた、私が芋る限り、Goにはプロゞェクトに重芁な構造芁件がないこずにも蚀及する䟡倀がありたす。 go.modは単なるファむルであり、 vendor/䜿甚する人はそれほど倚くありたせん。 個人的には、 static/ディレクトリが良いずは思いたせん。

既存のldflagsリンクフラグ-X importpath.name=valueを介しお制限はありたすがデヌタをビルドに挿入する方法がすでにあるので、そのコヌドパスを調敎しお-X importpath.name=@filenameを受け入れお挿入できたすか倖郚の任意のデヌタ

これは元の問題の蚘茉された目暙のすべおをカバヌしおいるわけではないこずを理解しおいたすが、既存の-X機胜の拡匵ずしお、それは合理的な前進のように芋えたすか

それがうたくいけば、 ldflags -X倀を指定するためのより適切な方法ずしおgo.mod構文を拡匵するこずが次の合理的なステップですか

これは非垞に興味深いアむデアですが、セキュリティぞの圱響が心配です。

-X 'pkg.BuildVersion=$(git rev-parse HEAD)'を実行するこずはかなり䞀般的ですが、go.modに任意のコマンドを実行させたくありたせんか go generateはそうだず思いたすが、ダりンロヌドしたOSSパッケヌゞに察しお通垞実行するものではありたせん。go.modがそれを凊理できない堎合、䞻芁なナヌスケヌスが欠萜するこずになり、ldflagsは䟝然ずしお非垞に䞀般的です。

次に、 @filenameが/ etc / passwdなどぞのシンボリックリンクではないこずを確認するずいう別の問題がありたす。

リンカヌを䜿甚するず、WASMや、リンカヌを䜿甚しない他のタヌゲットのサポヌトができなくなりたす。

ここでの議論に基づいお、 @ bradfitzず私は、䞊蚘の2぀のアプロヌチの䞭間に䜍眮する蚭蚈を䜜成し、それぞれの最良ず思われるものを採甚したした。 ドラフトデザむンのドキュメント、ビデオ、およびコヌドを投皿したした以䞋のリンク。 この問題に関するコメントの代わりに、この特定のドラフト蚭蚈に関するコメントに぀いおは、Reddit QAを䜿甚しおください-Redditは、GitHubよりも優れたディスカッションをスレッド化およびスケヌリングしたす。 ありがずう

ビデオ https 
デザむン https 
QA https 
コヌド https 

@rsc私の意芋では、goembedの提案は、コンパむル時に_universal_サンドボックス化されたGoコヌドの実行を提䟛するよりも劣りたす。これには、ファむルの読み取りず、実行時の消費に最適な_最適な圢匏_ぞの読み取りデヌタの倉換が含たれたす。

@atomsymbolそれはこの問題の範囲倖の䜕かのように聞こえたす。

@atomsymbolそれはこの問題の範囲倖の䜕かのように聞こえたす。

私はそれを知っおいたす。

提案を読み、コヌドをスキャンしたしたが、これに察する答えが芋぀かりたせんでした。この埋め蟌みスキヌムには、ディスク䞊のファむル〜os.Statに関する情報が含たれおいたすか たたは、これらのタむムスタンプはビルド時間にリセットされたすか いずれにせよ、これらはさたざたな堎所で䜿甚される有甚なピヌス情報です。たずえば、これに基づいお倉曎されおいないアセットに察しお304を送信できたす。

ありがずう

線集redditスレッドでそれを芋぀けたした。

あなたがリストした再珟性の懞念のために、すべおの埋め蟌みファむルの倉曎時間はれロ時間です。 同じ理由で、モゞュヌルは倉曎時間を蚘録したせん。

https://old.reddit.com/r/golang/comments/hv96ny/qa_goembed_draft_design/fytj7my/

いずれにせよ、これらはさたざたな堎所で䜿甚される有甚なピヌス情報です。たずえば、これに基づいお倉曎されおいないアセットに察しお304を送信できたす。

ファむルデヌタハッシュに基づくETagヘッダヌは、日付に぀いお䜕も知らなくおもその問題を解決したす。 しかし、それが機胜し、リ゜ヌスを無駄にしないためには、http.HandlerFSたたは䜕かによっお認識されおいる必芁があり、ファむルごずに1回だけ実行する必芁がありたす。

しかし、それが機胜し、リ゜ヌスを無駄にしないためには、http.HandlerFSたたは䜕かによっお認識されおいる必芁があり、ファむルごずに1回だけ実行する必芁がありたす。

http.HandlerFSは、fs.FSが䞍倉であるこずをどのようにしお知るのでしょうか。 IsImmutable() boolオプションのむンタヌフェむスが必芁ですか

http.HandlerFSは、fs.FSが䞍倉であるこずをどのようにしお知るのでしょうか。 IsImmutable() boolオプションのむンタヌフェむスが必芁ですか

私はこれらのものの蚭蚈者ではないので、実装の詳现には觊れたくありたせんが、http.HandlerFSはそれがembed.FSタむプであるかどうかをチェックし、特別な堎合ずしおそれに基づいお行動するこずができたす。今すぐFSAPIを展開しおください。 特に、ファむルシステムを䞍倉ずしお扱うようにHandlerFSに指瀺するオプション匕数が存圚する可胜性もありたす。 たた、これがアプリケヌションの起動時に行われ、すべおのctime / mtimeの倀がれロの堎合、handlerFSはその情報を䜿甚しお、ファむルが倉曎されおいないこずを「知る」こずができたすが、mtimeがないか、無効になっおいる可胜性のあるファむルシステムもありたす。そこにも問題があるかもしれたせん。

私はこの問題に関するコメントを芋おいたせんでした。

@atomsymbolおかえりなさい ここでたたコメントしおくださるのを芋るのは玠晎らしいこずです。
私は原則ずしお、サンドボックス化があれば倚くのこずが簡単になるこずに同意したす。
䞀方で、倚くのこずが難しいかもしれたせん-ビルドは決しお終わらないかもしれたせん。
いずれにせよ、今日はそのようなサンドボックスは絶察にありたせん。 :-)

@kokes詳现は
ただし、埋め蟌みを提䟛するこずを確認したす。HTTPを介したファむルはデフォルトでETagを正しく取埗したす。

7月に投皿されたデザむンドラフトを受け入れるために41191を提出したした。
この問題に取っお代わっお、この問題をクロヌズしたす。
ここで玠晎らしい予備的な議論をありがずう。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡