Dirijo uma empresa hospedada de integração contínua e executamos o código de nossos clientes no Linux. Cada vez que executamos o código, executamos em uma máquina virtual separada. Um problema frequente é que, às vezes, os testes de um cliente falham devido ao pedido de diretório de seu código verificado na VM.
Deixe-me entrar em mais detalhes. No OSX, o sistema de arquivos HFS + garante que os diretórios sejam sempre percorridos na mesma ordem. Os programadores que usam o OSX assumem que, se funcionar em sua máquina, deverá funcionar em qualquer lugar. Mas geralmente não funciona no Linux, porque os sistemas de arquivos linux não oferecem garantias de pedidos ao atravessar diretórios.
Como exemplo, considere que existem 2 arquivos, a.rb, b.rb. o a.rb define MyObject
e o b.rb usa MyObject
. Se a.rb for carregado primeiro, tudo funcionará. Se o b.rb for carregado primeiro, ele tentará acessar uma variável indefinida MyObject
e falhará.
Mas pior que isso, é que nem sempre falha. Como a ordem do sistema de arquivos no Linux não é solicitada, haverá uma ordem diferente em máquinas diferentes. Isso é pior, porque às vezes os testes passam e às vezes eles falham. Este é o pior resultado possível.
Portanto, minha pergunta é: existe uma maneira de tornar a ordenação do sistema de arquivos repetível. Alguma flag para ext4, talvez, que diz que sempre irá percorrer diretórios em alguma ordem? Ou talvez um sistema de arquivos diferente que tenha essa garantia?
fonte
Respostas:
Sei que não é a resposta que você está procurando, mas acredito que a solução correta é evitar depender da ordem dos arquivos em um diretório. Talvez seja sempre consistente em todos os sistemas de arquivos HFS +, e talvez você possa encontrar uma maneira de torná-lo consistente no ext4 ou em algum outro sistema de arquivos também, mas isso lhe custará mais problemas a longo prazo do que salvará. Alguém mais usando o seu aplicativo terá uma surpresa desagradável quando não perceberem que ele é compatível apenas com alguns tipos de sistemas de arquivos e não com outros. A ordem pode mudar se um sistema de arquivos for restaurado do backup. Você provavelmente terá problemas de compatibilidade porque a ordem consistente HFS + e a ordem consistente ext4 podem não ser as mesmas.
Basta ler todas as entradas do diretório e classificar a lista lexicograficamente antes de usá-la. Assim como
ls
faz.Você menciona arquivos
a.rb
eb.rb
, mas se estamos falando sobre arquivos de origem da linguagem de programação, cada arquivo já não deveria ser responsável por garantir que ele importe todas as suas dependências?fonte
A chamada POSIX no Linux readdir () não garante nenhuma ordem consistente. Se você deseja resultados ordenados, o aplicativo que está manipulando arquivos é responsável por ordenar como eles são apresentados às funções de chamada.
/programming/8977441/does-readdir-guarantee-an-order
Agora, como você disse que esse era o código do seu cliente e não pode corrigi-lo, é possível alterar as bibliotecas vinculadas usadas para fornecer uma chamada readdir () consistente. Isso exigiria algum trabalho e valeria a pena a sua própria pergunta. Para uma referência rápida a isso, consulte http://www.ibm.com/developerworks/linux/library/l-glibc/index.html .
Alterar isso pode gerar outras séries inteiras de problemas que talvez eu não consiga prever. Você é fortemente advertido, mas pode ser uma solução se seu cliente não puder ser educado adequadamente.
fonte
Informe seu cliente que existe uma dependência inerente ao pedido que deve ser explicitamente declarada. Ofereça-se para ajudar o cliente a expressar a dependência de forma que uma compilação funcione em todos os sistemas e faça com que o cliente adote o fluxo alterado que captura a dependência do pedido de compilação.
Se o cliente quiser poder compilar em outras máquinas, seria grosseiro da parte deles pensar que é gratuito.
fonte
O Linux moderno (ext4) adiciona um índice de árvore B para listas de arquivos. Um de seus efeitos é a ordem dos arquivos padrão, depende de um hash de seus nomes.
Para desativar esse recurso, use:
fonte