Packages
Um package é um diretório com um talor.mod dentro. talor install resolve as linhas require do manifest, copia ou baixa o que a cache não tem, verifica o digest de cada árvore, e escreve talor.lock.
talor install [<dir>]talor build faz a mesma resolução quando precisa: escreve o lock de uma árvore que não tem um, e copia para a cache um package que o lock nomeia e que a cache não tem. Então o caminho do dia a dia é só talor build, e o install é a resolução sem um build. Um require que o lock não nomeia é recusado pelo build, nomeando install, e um build nunca muda um lock. Nenhum comando alcança a rede ainda.
O que um require nomeia
Um require escreve o nome da dependência, a fonte de onde ela vem, e o que essa fonte recebe:
require util path libs/util
require greet file:// ../greet
require crypto git https://example.com/crypto.git v1.0.2
require parser registry 1.2.3| Fonte | O que ela recebe | O que o install faz com ela |
|---|---|---|
path | um diretório dentro do package | nada: a árvore é lida onde está, e não entra nem no lock nem na cache |
file:// | um caminho em qualquer lugar | copia a árvore para a cache, o que é uma cópia e não um download |
git | um repositório e, opcionalmente, uma revisão | nomeada no manifest; o download ainda não está escrito |
registry | uma versão | nomeada no manifest; o download ainda não está escrito |
workspace | nada | nada: o require de mesmo nome do próprio build raiz diz de onde ele vem |
As duas fontes que não precisam de rede são as duas que funcionam hoje, e uma linha git ou registry é recusada onde está, nomeando a fonte:
'crypto' comes from 'https://example.com/crypto.git', which needs the network; 'path' and 'file://' are the sources that need nothingUm package é guardado na cache sob o nome e a versão que o próprio talor.mod dele declara, então uma árvore cujo manifest nomeia outro nome que o require que a alcançou é recusada em vez de guardada sob qualquer um dos dois:
'../greet' declares the name 'greet', and 'sib' is the name it is required underUm nome também é como um use a alcança: require greet file:// ../greet é o que faz use greet; resolver sob a árvore daquele package.
O lock
talor.lock é o que prende um build. Ele é escrito inteiro e em ordem de nome, então uma execução que não mudou nada escreve os mesmos bytes:
lock 1
package greet 1.0.0 file://../greet sha256:528b5bba55b595517079e58ef1cf431fb9c7fba60013166a11f58145cd46ce29A primeira linha é a versão do formato e nada mais; um lock cuja primeira linha nomeia uma versão que esta toolchain não escreve é recusado em vez de lido pela metade, porque a parte de um formato mais novo que por acaso se parece com este construiria a árvore errada. Cada linha depois dela carrega o digest da árvore como o install a deixou, e o build o recalcula: uma cache que mudou é uma recusa e não um aviso.
Uma entrada que já está no lock, já está na cache e cujo digest ainda bate não é copiada de novo, então um segundo talor install não faz trabalho.
O que ele recusa
- Sem manifest: um package é um diretório com um
talor.mod, e obuildrecusa do mesmo jeito. - Uma árvore
file://que não está lá, nomeando o caminho. - Uma árvore cujo manifest nomeia outro nome, nomeando os dois.
- Uma árvore cujo manifest não nomeia versão: a versão sob a qual um package é guardado é a dele.
- Um
requirecuja fonte precisa da rede, nomeando a fonte e dizendo quepathefile://são as fontes que não precisam de nada. - Um
requireescrito duas vezes, recusado pelo leitor de manifest como obuildo recusa.
Vendoring
talor vendor [<dir>]vendor copia cada package que o talor.lock nomeia da cache para <dir>/vendor/<name>/<version>/, verificando cada cópia contra o digest do lock. Uma árvore com um diretório vendor/ faz o build numa máquina sem cache.