2 pontos por GN⁺ 2025-04-09 | 1 comentários | Compartilhar no WhatsApp
  • Lux é um novo gerenciador de pacotes que reúne criação, manutenção e distribuição de código Lua em uma CLI simples, buscando levar ao ecossistema Lua um fluxo de desenvolvimento familiar, como o do cargo
  • Após pouco mais de um ano de desenvolvimento, chegou a um estado muito utilizável para o trabalho do dia a dia, embora suporte a MSVC, mensagens de erro e cobertura de casos extremos ainda permaneçam como tarefas antes do lançamento 1.0
  • Integra em um único fluxo um modelo de projeto baseado em lux.toml, geração automática de rockspec, lockfile, builds paralelos, instalação de headers do Lua e execução de formatação, lint e testes
  • Mantém compatibilidade com o ecossistema Luarocks, mas foca em reduzir o peso de compatibilidade antiga, a imprevisibilidade entre sistemas e a experiência lenta de instalação e sincronização
  • Os principais casos de uso são distribuição de plugins do Neovim e integração com Nix, e a próxima etapa inclui reescrever o rocks.nvim para usar Lux em vez de Luarocks

O fluxo de gerenciamento de pacotes Lua oferecido pelo Lux

  • Lux é um novo gerenciador de pacotes para criação, manutenção e distribuição de código Lua
  • A CLI é inspirada em gerenciadores de pacotes bem conhecidos, como o cargo do Rust
  • Atualmente, já alcançou um nível “muito utilizável para o trabalho do dia a dia”
    • Suporte a MSVC, mensagens de erro e cobertura de casos extremos ainda faltam
    • Essas correções fazem parte do plano para o lançamento 1.0

Modelo de projeto e integração de ferramentas de desenvolvimento

  • Dá suporte à portabilidade entre sistemas e permite builds e instalações em paralelo
  • O Lux cuida da instalação dos headers do Lua
    • Os alvos suportados são Lua 5.1, 5.2, 5.3, 5.4 e luajit
    • O autor do pacote só precisa declarar quais versões de Lua são compatíveis
  • O crate lux-lib é totalmente embutível e também pode ser compilado para expor uma API Lua
  • Oferece um conceito de projeto centrado no arquivo lux.toml
    • Gera automaticamente um rockspec a partir de lux.toml
    • Isso reduz o peso de manter manualmente vários arquivos rockspec no repositório
  • O lockfile busca builds e ambientes de desenvolvimento reproduzíveis
    • Armazena hashes do código-fonte e do rockspec
    • Esses hashes podem ser usados para facilitar a integração do Lux com o Nix
  • Formatação e lint de código também estão incluídos na CLI
  • Há suporte nativo para executar testes com base em busted
    • É possível usar o Neovim como interpretador Lua
    • Um ambiente puro é montado

Diferenças em relação ao Luarocks

  • O Luarocks tem escopo amplo, mas há o problema de que, por causa de cerca de 20 anos de peso de compatibilidade, é difícil adaptá-lo ao desenvolvimento moderno em Lua
  • O Lux busca um novo começo e usa TOML como formato principal de manifesto
    • Pela CLI, é possível adicionar, remover, fixar e atualizar dependências
    • Em um diretório de projeto com lux.toml, comandos como build constroem o projeto e o instalam em uma árvore local ao projeto
    • Durante o processo de build, ele cria um lockfile das dependências do projeto, permitindo reproduzir as mesmas dependências em sistemas compatíveis
  • A forma de incentivar o uso de SemVer também é diferente
    • O Luarocks permite versões arbitrárias após a versão de patch
    • Por exemplo, 1.0.1.0.0.0.2 é válido no Luarocks, mas é visto como algo sem significado útil
    • O Lux também faz o parse disso, mas trata os valores após a versão de patch como versão de pré-lançamento
  • Os builds paralelos são inspirados na Nix store
    • O Lux faz hash do diretório de instalação para evitar conflitos entre pacotes e possibilitar builds paralelos sem risco de corromper o sistema de arquivos
    • Mais detalhes relacionados estão no guia de conflitos de pacotes do Lux

Uso no ecossistema Neovim

  • Depois do suporte a Luarocks em rocks.nvim e lazy.nvim, o Luarocks vem ganhando popularidade como forma de distribuir plugins do Neovim
  • Ainda assim, o uso atual do Luarocks tem limitações por não oferecer portabilidade completa e por tornar difícil prever os resultados em cada sistema
  • Como o Luarocks é escrito em Lua, instalar muitos pacotes e sincronizar o plugin rocks.nvim era muito lento
  • O uso do Lux não é destrutivo e atualmente não interfere no método baseado em Git usado para distribuir plugins do Neovim
  • Com a flag --nvim, ele instala pacotes em uma estrutura de árvore compatível com :h packages do Neovim

Lockfile para integração com Nix

  • Quando um plugin do Neovim existe como pacote Luarocks, o nixpkgs o usa como fonte de referência
    • Isso porque, em um gerenciador de pacotes adequado, a responsabilidade por declarar dependências fica com o autor do pacote
  • O suporte a lockfile do Luarocks é básico e não inclui hashes do código-fonte
  • Tanto Luarocks quanto Lux oferecem suporte a dependências conflitantes por meio do luarocks.loader
  • O nixpkgs tem dificuldade para adicionar de forma razoável várias versões da mesma dependência ao conjunto de pacotes
  • O lux.lock do Lux armazena o hash do código-fonte e o hash do rockspec de cada dependência
    • Se a URL do código-fonte for um repositório Git, o Lux armazena um NAR hash
    • Assim como o Cargo.lock, o lux.lock pode ser usado para criar uma fixed-output derivation com todas as dependências

Próximos passos e documentação

  • A prioridade atual é corrigir bugs e melhorar as mensagens de erro
  • O rocks.nvim será reescrito para usar Lux internamente no lugar do Luarocks
    • O objetivo dessa reescrita é elevar a velocidade do rocks.nvim ao nível de outros gerenciadores de plugins
    • Se der certo, isso servirá como um caso mostrando que o Lux também pode ser embutido em outros lugares
    • Como exemplo, é citado o lazy.nvim, que no passado teve problemas relacionados ao Luarocks
  • Usuários iniciais podem ver tutoriais e guias no site de documentação
  • Perguntas ou issues podem ser enviadas pelo GitHub discussions ou pelo issue tracker
  • O Lux está sob licença LGPLv3.0+, e o logo do Lux está sob licença CC BY-NC-SA 4.0 de © 2025 Kai Jakobi

1 comentários

 
GN⁺ 2025-04-09
Opiniões do Hacker News
  • O calcanhar de Aquiles das linguagens de script é o ambiente de execução. Pessoalmente, não uso Neovim, mas achei que a adoção do Neovim impulsionaria avanços nessa área no lado do Lua.
    Bryan Cantrill chamou JavaScript de “LISP vestido de C”; em certo sentido, Lua me parece o oposto disso, e é por isso que gosto. Só que nunca precisei usá-la no trabalho.

    • Não sei qual é a base para dizer que JavaScript é Lisp vestido de C. Também não sei o que Lua tem a ver com Lisp, e não há nenhuma sintaxe de Lisp.
  • Pelo que sei, projetos como o Koreader[1] usam Lua como linguagem principal da aplicação. Se você conseguir convencer um desses projetos a migrar, isso poderia dar alguma confiança quanto à maturidade e à popularidade da ideia.
    [1]: https://github.com/koreader/koreader

    • Boa sugestão. O Lux ainda vai precisar de algum tempo para amadurecer, mas compilar um grande projeto multiplataforma como o koreader certamente pode ser um bom objetivo.
  • Parece muito bom. Uso bastante Lua, e o luarocks sempre teve uma orientação forte demais, então quase nunca serviu para o que eu precisava.
    Se você foge um pouco de “instalar bibliotecas para executar diretamente no sistema local”, já fica travado desde o começo. Se você tem um ambiente de scripting embutido que usa pacotes Lua e quer empacotar e distribuir scripts junto com as dependências, era melhor desistir.
    Não sei se esta ferramenta é melhor para esse caso, mas, mesmo que não seja, o luarocks é, sendo generoso, tosco e irritante de usar.

    • A comunidade Lua depende enormemente de bibliotecas em C, e praticamente todo pacote do luarocks tenta compilar uma biblioteca, o que o torna basicamente inútil no Windows.
  • Projeto interessante. Gostaria de trabalhar em conjunto para criar um suporte melhor a Lua no Pixi por meio do ecossistema conda-forge.
    Já estamos empacotando lua e algumas extensões em C. Extensões em C são uma área central do Pixi, então acho que pode haver um bom encaixe.
    Documentação do pixi.sh e pacote lua no registro: https://prefix.dev/channels/conda-forge/packages/lua

    • Parece uma boa ideia. Abri uma issue no repositório, então fique à vontade para me marcar por lá.
  • Pergunto porque não vi isso aqui nem nos sites relacionados: ele se integra nativamente a package.path e package.cpath, detecta instalações não padrão mas amplamente usadas como brew(1), e permite instalar no estilo GitHub :user/:repository?
    O projeto parece legal e bem feito.

    • Os comandos lx run e lx lua configuram PATH, LUA_PATH e LUA_CPATH. Também há o comando lx path para configurar essas variáveis de ambiente.
      A detecção da instalação do Lua usa pkg-config por padrão e, se não encontrar, tenta instalar Lua por meio dos crates lua_src e luajit_src. No futuro, também poderemos adicionar suporte a outras ferramentas, como vcpkg.
      A instalação no estilo GitHub :user/:repository ainda não funciona. Planejo adicioná-la ao lux.toml/à especificação de dependências, mas provavelmente não vou permitir publicar esse tipo de rockspec no luarocks.org. Não quero ser a causa de as pessoas enviarem pacotes que não podem ser compilados com o luarocks.
  • Então um gerenciador de pacotes para uma linguagem projetada para ser embutida em C e que depende muito de bibliotecas em C é escrito em Rust, e, embora Lua em si tenha sido criada como linguagem de configuração para programas em C, a configuração é em TOML?
    Dispenso. O Luarocks tem limitações e provavelmente precisa ser reescrito, mas deveria usar uma linguagem adequada ao ecossistema e seguir a cultura do ecossistema Lua. Rust e Cargo estão exatamente no lado oposto de Lua.

    • Lua evoluiu e hoje é usada em muito mais lugares do que o propósito para o qual foi criada inicialmente.
  • Pessoalmente, estou bem cansado desses gerenciadores de pacotes específicos de linguagem. Não parece o caminho certo; uma abordagem como a do nix parece muito melhor.

    • Uma das motivações do Lux é melhorar os ecossistemas Lua e Neovim no nixpkgs.
  • Um gerenciador de pacotes para Lua que depende de Rust.

    • Não vejo grande problema. A maioria dos gerenciadores de pacotes oferece suporte à instalação de pacotes somente binários.
    • Você pode se surpreender com o quão bem isso funciona.
    • E ainda usa TOML.
  • Gostei. Faz bastante tempo que eu queria ter uma forma de fazer instalações reproduzíveis de pacotes Lua em várias máquinas.

    • Já consegui criar estados reproduzíveis de instalação de pacotes Lua em várias máquinas, mas uso Lua principalmente de duas formas.
      Uma é em forma “crua”, linkando-a a uma VM interna e gerenciando a base de código .lua como parte da compilação do projeto; a outra é como ferramenta de sistema, usando adequadamente ferramentas como luarocks --local e luaenv dentro de Makefile/CMakeLists.txt, com um pouco de luastatic misturado para os bundles de distribuição.
      Sinceramente, isso não é muito diferente de Python ou de outras linguagens de script que podem ser embarcadas junto. A diferença é que sempre é preciso separar o /bin/script_language fornecido pelo sistema da linguagem usada como ferramenta de desenvolvimento/motor de scripting dentro de um projeto maior, ou como ferramenta para a bancada local.
      Um dos motivos pelos quais gosto muito de Lua é que é relativamente fácil e divertido empacotar bibliotecas, linkar bytecode e embrulhar bundles para oferecer aos usuários do sistema operacional de destino uma instalação com um clique. Claro, ainda é preciso fazer algum trabalho manual.
  • É excelente, mas tenho a forte impressão de que vai na direção oposta ao design do Lua. Lua foi projetada como uma linguagem simples para embutir, e aqui “gerenciamento de pacotes” é algo mais próximo de baixar e descompactar alguns zips, enquanto “gerenciamento de versões” é escolher se você vai usar compatibilidade com 5.1 ou com 5.4.