1 pontos por GN⁺ 5 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Nix Flakes reúne dependências de projeto, travamento, esquema de saídas e ambientes de desenvolvimento em torno de flake.nix e flake.lock, enquanto o Guix oferece o mesmo tipo de funcionalidade por meio da combinação de ferramentas ortogonais como channels, manifests, guix describe, guix shell e operating-system
  • Flakes fixa dependências com inputs por projeto e flake.lock gerado automaticamente, enquanto o Guix monta ambientes reproduzíveis com guix describe por usuário, channels.scm com commits registrados no projeto e guix time-machine
  • Pureza é imposta no Flakes por restricted evaluation, e no Guix é alcançada por projeto por meio da estrutura de módulos Scheme, entradas explícitas e contêineres de build isolados
  • Estrutura de saída: Flakes fornece attrsets padrão como packages, devShells e nixosConfigurations, enquanto o Guix usa registros e arquivos Scheme transparentes como <package>, manifest, operating-system e service, consumidos diretamente por cada comando
  • Critério de escolha: se você prefere um único ponto de entrada e um esquema padrão, Flakes é mais adequado; se prefere combinar ferramentas pequenas e independentes, Guix tende a se encaixar melhor

Comparação principal

  • Não existe um único recurso do Guix equivalente ao Nix flake; enquanto o Nix Flakes resolve vários problemas com um grande recurso unificado, o Guix responde com a combinação de ferramentas menores e ortogonais
  • O Guix reutilizou o daemon do Nix e compartilha os componentes em C++ responsáveis por isolamento de build e gerenciamento do store
  • O Guix reimplementou em Guile Scheme a maior parte do que fica acima do daemon do Nix, incluindo linguagem, definições de pacotes e sistema de serviços
  • Guix e Nix compartilham o formato de derivation ATerm e a linhagem do daemon, mas a estrutura acima do daemon é organizada à maneira do próprio Guix
  • O Guix tem as capabilities oferecidas pelo Flakes, mas as fornece de outra forma

Estrutura básica de um Nix Flake

  • Um Nix flake é uma árvore de código-fonte com um arquivo flake.nix na raiz, geralmente em forma de repositório Git
  • A presença de flake.nix transforma a árvore de código-fonte em um flake, e o arquivo tem uma estrutura com itens como description, inputs e outputs
  • description é uma string legível por humanos que indica o que o flake fornece
  • inputs declara dependências como outros flakes, repositórios Git e tarballs, que o Nix busca e avalia antes de passá-las para a função outputs
  • outputs é uma função que recebe os inputs resolvidos e um input especial self, e retorna um attrset estruturado contendo packages, shells de desenvolvimento, configurações do NixOS, overlays e mais
  • Estrutura de exemplo e alvos de execução

    • No exemplo de inputs, nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; significa que o branch nixos-unstable do repositório NixOS/nixpkgs no GitHub será obtido
    • O flake de exemplo usa supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ]; e nixpkgs.lib.genAttrs para gerar saídas para várias arquiteturas de CPU
    • Flakes exige o nível packages.<system>, e no exemplo o pacote default é definido em packages com pkgs.buildGoModule
    • src = ./.; usa o repositório Git inteiro como código-fonte
    • devShells define o shell de desenvolvimento consultado por nix develop, e no exemplo usa pkgs.mkShell e buildInputs = with pkgs; [ go gopls gotools ];
  • flake.lock e avaliação pura

    • Ao executar um comando Nix sobre um flake, o Nix gera o arquivo JSON flake.lock, que fixa todos os inputs e inputs transitivos em revisões exatas
    • flake.lock é o arquivo de lock que permite reprodutibilidade de build entre máquinas e ao longo do tempo
    • Flakes impõe avaliação pura, de modo que $NIX_PATH, builtins.currentSystem e variáveis de ambiente não entram implicitamente; tudo precisa ser explícito
    • As funções desempenhadas pelo Flakes podem ser resumidas como: declaração de dependências, fixação de dependências, imposição de pureza, fornecimento de um esquema padrão de saídas, compartilhamento reproduzível e definição de ambientes de desenvolvimento

A abordagem correspondente no Guix

  • O Guix já tinha soluções para uma parte considerável dos recursos dos Flakes antes de os Flakes serem introduzidos no Nix 2.4 em 1º de novembro de 2021
  • O mecanismo de canais do Guix foi introduzido por volta de 2018–2019
  • A solução do Guix é ortogonal, e cada ferramenta pode ser usada de forma independente sem adotar uma abstração monolítica única
  • Canais e declaração de dependências

    • No Flake, as dependências são declaradas diretamente dentro de flake.nix, e no exemplo são usados nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; e home-manager.url = "github:nix-community/home-manager";
    • Em um input de Flake, inputs.nixpkgs.follows = "nixpkgs"; faz com que home-manager use o nixpkgs do flake atual em vez de trazer seu próprio input nixpkgs, evitando a situação em que surgem duas cópias diferentes de nixpkgs
    • Os canais do Guix são repositórios Git que incluem módulos Guile; normalmente contêm definições de pacotes, mas também podem incluir serviços, configurações de sistema e código Scheme arbitrário
    • Os canais do Guix são declarados em ~/.config/guix/channels.scm, e esse arquivo Scheme retorna uma lista de registros de canais
    • guix pull busca e compila todos os canais, disponibilizando esses módulos para uso em todos os comandos guix
    • Os canais podem declarar dependências de outros canais usando o arquivo .guix-channel na raiz do repositório
    • A dependência entre canais no Guix é aproximadamente semelhante aos inputs de um flake, e as dependências transitivas de canais são buscadas junto quando guix pull é executado
  • Dependências por projeto e dependências por usuário

    • Os Flakes seguem uma abordagem por projeto, em que cada repositório tem seu próprio flake.nix e seus inputs, enquanto os canais seguem uma abordagem system-wide ou por usuário, em que channels.scm se aplica a todas as invocações de guix
    • Os Flakes oferecem suporte natural para que projetos diferentes tenham conjuntos de dependências diferentes; no Guix, para obter o mesmo efeito, normalmente se usa guix time-machine ou perfis separados
    • Os Flakes usam sintaxe parecida com URL, como github:NixOS/nixpkgs e git+https://..., enquanto os canais usam URLs Git simples
    • A sintaxe de Flake é mais ergonômica para referências rápidas, enquanto os canais são mais simples e explícitos
    • Os Flakes oferecem suporte a repositórios sem flake.nix como inputs non-flake com flake = false;
    • No Guix, como um canal é um repositório Git que contém arquivos Scheme, não é necessário nenhum opt-in especial; qualquer repositório com módulos Guile pode se tornar um canal

Fixação, reprodutibilidade e viagem no tempo

  • flake.lock

    • flake.lock é um grafo JSON, e todos os inputs são fixados com hash de commit exato; o Nix verifica o narHash, que é o hash da árvore de código-fonte inteira que foi buscada
    • flake.lock é commitado no repositório, então quem fizer clone recebe as mesmas versões de dependências
    • Em flake.lock, original é o alvo solicitado e locked é o alvo efetivamente obtido
    • O sistema em duas camadas de flake.lock permite atualizações seletivas, mantendo o restante, como em nix flake lock --update-input nixpkgs
  • guix describe e guix time-machine

    • O Guix registra os commits exatos de todos os canais quando guix pull é executado, e guix describe mostra essas informações
    • A saída de guix describe inclui número da geração, data, indicação de atual, nome do canal, URL do repositório, branch e commit
    • Os commits de canais registrados no Guix correspondem a um lock file, mas existem como um perfil Guile em ~/.config/guix/current, e não como um arquivo no diretório do projeto
    • Para compartilhar um ambiente reproduzível, no Guix é possível usar guix time-machine
    • guix time-machine --commit=8a1ab328 -- shell -m manifest.scm fixa o próprio Guix em uma revisão específica e então executa guix shell usando as definições de pacotes dessa revisão
    • guix time-machine baixa e compila essa revisão quando necessário, criando um ambiente isolado em que as definições de pacotes correspondem exatamente ao estado daquele commit
    • Também existe um padrão no Guix de versionar no repositório um channels.scm com commits fixados
    • guix time-machine -C channels.scm -- shell -m manifest.scm reproduz o ambiente exato usando o channels.scm incluído no repositório
  • Diferenças entre as duas abordagens

    • flake.lock é automático e por projeto, enquanto guix describe é automático e por usuário
    • Um channels.scm com commits fixados oferece pinning por projeto no Guix, mas de forma manual
    • O Guix está melhorando a ergonomia do pinning por projeto, mas o fluxo de trabalho atual ainda exige uma configuração mais explícita
    • flake.lock é um grafo JSON legível por máquina, e o equivalente no Guix é um arquivo Scheme que lista canais com hashes de commit
    • As duas abordagens atingem o objetivo de pinning de dependências, mas o lock de flake é mais estruturado por ser um grafo completo de dependências com entradas original e locked para todos os inputs transitivos
    • guix time-machine é um recurso sem equivalente direto em Flakes, pois permite mover-se não apenas para versões de dependências fixadas, mas para um estado histórico completamente diferente da coleção de pacotes

Modelo de pureza

  • Flakes são executados em um contexto de avaliação restrito, e o uso de builtins.currentSystem, builtins.getEnv e $NIX_PATH é proibido ou ignorado
  • Em Flakes, tudo deve vir de inputs declarados, o que dificulta a criação de dependências acidentais de estado implícito
  • O trade-off da avaliação pura em Flakes é que parâmetros system explícitos são necessários em vários pontos para detectar o sistema, e não é possível ler variáveis de ambiente
  • Quando é necessário um escape hatch impuro em Flakes, é preciso passar --impure explicitamente
  • O Guix não precisa de um modo de avaliação puro separado, pois a avaliação já é pura por convenção
  • Módulos Guile não acessam variáveis de ambiente a menos que elas sejam passadas explicitamente
  • O Guix não tem um equivalente a $NIX_PATH, e resolve pacotes por meio do sistema de módulos, não por um caminho de busca
  • O Guix não tem um conceito equivalente a builtins.currentSystem, e os sistemas são explicitados por metadados do pacote e pela flag --system
  • As builds do Guix também são puras, e as builds são executadas em contêineres isolados onde apenas inputs declarados explicitamente ficam visíveis
  • Nas builds do Guix, não há acesso a /usr/bin, /etc nem à rede, e exceções de acesso à rede se limitam a fixed-output derivations
  • A forma de sandboxing de build é essencialmente a mesma no Nix e no Guix
  • O Guix alcança pureza no nível da arquitetura por meio da estrutura de módulos Scheme, enquanto Flakes impõe pureza ao sobrepor um modo de avaliação restrito sobre um sistema originalmente impuro

Esquema de saída e modelo de dados

  • Esquema de saída de Flake

    • Flakes definem um esquema padrão para outputs, e packages.<system>.<name> é usado por nix build, devShells.<system>.<name> por nix develop, e apps.<system>.<name> por nix run
    • O esquema de saída de Flake também inclui nixosConfigurations.<name>, overlays.<name>, nixosModules.<name>, formatter.<system>, templates.<name> e checks.<system>.<name>
    • A padronização do esquema de saída de Flake faz com que nix build ., nix run e nix flake show consultem locais consistentes, aumentando a discoverability
    • A desvantagem do esquema de saída de Flake é sua rigidez; adicionar tipos de saída arbitrários exige modificar o próprio Nix, embora exista um pequeno mecanismo de extensão
    • Por causa do parâmetro <system> do Flake, o suporte multiplataforma precisa ser tratado explicitamente, e são usadas funções auxiliares ou bibliotecas como forAllSystems, flake-utils e flake-parts
  • Tipos de dados de primeira classe no Guix

    • O Guix não tem um único esquema de saída como Flakes; em vez disso, possui tipos de dados de primeira classe que podem ser consumidos por vários comandos
    • No Guix, pacotes são definidos como registros <package> e usados por guix install e guix build
    • No Guix, manifests são definidos como arquivos Scheme e usados por guix shell -m e guix package
    • No Guix, configurações de sistema são definidas como operating-system e usadas por guix system reconfigure
    • No Guix, configurações de home são definidas como home-environment e usadas por guix home reconfigure
    • No Guix, serviços são definidos como registros <service> e usados pelo campo services de operating-system
    • No Guix, channels são repositórios Git e guix pull é usado para eles
    • No Guix, variantes de pacote são procedimentos Scheme, e --with-input e --transform são usados
  • Arquivos e definições de pacote

    • Um projeto Guix pode fornecer uma combinação de um channel com definições de pacote, manifest.scm para desenvolvimento, system.scm para implantação e declarações operating-system ou home-environment
    • No Guix, esses arquivos não exigem um arquivo especial de ponto de entrada; são apenas arquivos Scheme que definem valores Scheme
    • No Guix, basta indicar o arquivo ao subcomando guix correspondente para que o comando o processe, sem necessidade de ceremony adicional ou validação de esquema
    • Um exemplo de manifest.scm declara um ambiente de desenvolvimento passando uma lista de nomes de pacotes "guile", "guile-git" e "guile-json" para specifications->manifest
    • Um exemplo de mylib.scm define um registro <package>, o equivalente no Guix a uma derivation do Nix, e seus campos de pacote podem ser consultados programaticamente
    • Um exemplo de definição de pacote contém (name "mylib"), (version "0.1.0"), (source (local-file ".")), (build-system gnu-build-system), (inputs (list guile guile-git)), (home-page "https://example.com";) e (license gpl3+)
    • local-file no Guix traz os arquivos do diretório atual no momento da build, de forma semelhante a src = ./.; no Nix
    • gnu-build-system no Guix segue o padrão ./configure && make && make install, e o Guix também tem outros sistemas de build, como cmake-build-system e python-build-system
    • Ao contrário do Nix, em que stdenv fornece gcc e coreutils implicitamente, o Guix mantém todas as dependências explícitas

Ambiente de desenvolvimento

  • No exemplo de devShells do Flakes, usa-se devShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; };
  • mkShell cria uma derivation que monta um ambiente de shell na hora do build; buildInputs entra no PATH dentro do shell, e shellHook executa bash arbitrário ao entrar no shell
  • É possível entrar no dev shell do Flake com nix develop ou, para um shell nomeado, com nix develop .#my-shell
  • O ambiente de desenvolvimento do Guix pode ser definido em manifest.scm passando uma lista de strings de especificação de pacote para specifications->manifest
  • O manifest de exemplo do Guix declara "go", "gopls", "go-tools"
  • É possível entrar em um shell baseado em manifest do Guix com guix shell -m manifest.scm
  • No Guix, em um ambiente ad hoc, também é possível passar apenas nomes de pacotes na linha de comando, como em guix shell go gopls go-tools, sem usar arquivo
  • guix shell oferece suporte a --container para isolamento completo, --emulate-fhs para executar programas que esperam o layout padrão de filesystem do Linux, e --nesting para executar o Guix dentro de um contêiner do Guix
  • Os manifests do Guix são arquivos Scheme independentes, não incorporados em uma estrutura maior como flake.nix
  • guix shell pode funcionar sem arquivo, mas nix develop precisa de um flake ou do shell.nix da interface legada
  • Flakes oferecem dev shells nomeados como devShells.x86_64-linux.test e devShells.x86_64-linux.default
  • Em vez de dev shells nomeados, os manifests do Guix usam arquivos separados lado a lado, como manifest.scm e test-manifest.scm
  • Tanto Nix Flakes quanto Guix oferecem suporte a desenvolvimento em contêiner

Configuração do sistema

  • NixOS e Flakes

    • No exemplo de nixosConfigurations do Flakes, nixpkgs.lib.nixosSystem recebe uma lista de módulos do NixOS e gera uma derivation completa do sistema, incluindo kernel, services, arquivos de configuração etc.
    • Um exemplo de comando para implantar o NixOS com base em Flake é nixos-rebuild switch --flake .#myhost
    • O exemplo nixosConfigurations.myhost inclui system = "x86_64-linux"; e modules = [ ./configuration.nix home-manager.nixosModules.home-manager ];
    • Os módulos do NixOS usam um sistema de módulos baseado em mesclagem por prioridade com options, config, mkIf, mkDefault e mkForce
    • No sistema de módulos do NixOS, mesmo que vários módulos definam a mesma opção, o sistema resolve as prioridades, o que facilita evitar conflitos mesmo quando dezenas de módulos contribuem para a mesma configuração
  • Guix operating-system

    • O operating-system do Guix não é uma function, e sim um record em Scheme, em que cada field é um valor nomeado e tipado validado pelo Guix
    • Um exemplo de comando para implantar um sistema com Guix é guix system reconfigure config.scm
    • O record operating-system de exemplo inclui (host-name "myhost"), (timezone "Etc/UTC"), configuração de bootloader, file systems e services
    • O exemplo de configuração de bootloader no Guix usa grub-efi-bootloader com o alvo "/boot/efi", e o Guix oferece suporte a GRUB, U-Boot e outros
    • Os file systems do Guix são declarados como lista, e %base-file-systems fornece os padrões para /dev, /proc, /sys etc.
    • Os services do Guix formam um grafo acíclico direcionado (DAG), e cada service pode estender outros services
    • %base-services fornece os services essenciais, como o sistema de init Shepherd, syslog, rede e outros
    • A configuração de sistema do Guix não exige um tipo de output especial; basta apontar para um arquivo que retorne um record operating-system no guix system
    • A composição de services no Guix facilita escrever novos services que se conectam ao sistema existente de maneiras arbitrárias

Descoberta e registros

  • Flakes têm flake.nix, um ponto de entrada padrão que declara dependências do projeto, outputs e um schema detectável em um único arquivo
  • Projetos Guix podem usar arquivos baseados em convenção, como manifest.scm, channels.scm, guix.scm e package.scm
  • Há um movimento para padronizar guix.scm como arquivo de projeto reconhecido automaticamente por guix shell, mas isso ainda não está tão estabelecido quanto flake.nix
  • Flakes têm o registro global flake-registry, que mapeia nomes curtos para URLs; os exemplos incluem nix run nixpkgs#hello e nix build github:NixOS/nixpkgs#firefox
  • O Guix usa especificações de pacote para uma conveniência parecida; os exemplos incluem guix shell hello e guix install firefox
  • O Guix não tem um equivalente de registro para apontar um repositório Git arbitrário com um nome curto, então usa a URL diretamente
  • O registro do Nix às vezes tem sido fonte de confusão porque nem sempre fica claro se nixpkgs é uma entrada do registro, um caminho local ou outro destino
  • nix flake show é um comando que mostra em visualização de árvore tudo o que um flake oferece
  • O Guix tem guix search para pacotes e guix system search para services, mas não há um comando equivalente que mostre tudo o que um projeto ou repositório específico oferece; é preciso verificar os arquivos Scheme diretamente
  • Flakes têm boa discoverability porque nix flake show apresenta uma visão consistente do que o projeto oferece
  • Projetos Guix são mais ad hoc; é preciso saber quais arquivos olhar, e não existe um arquivo padrão único de ponto de entrada
  • O Guix tem grande flexibilidade porque tudo é Scheme, então é possível definir e combinar o que se quiser sem schema

Modelo de pacotes e reescrita de grafos

  • No Nix, um pacote é uma função que retorna uma derivation por meio de uma chamada stdenv.mkDerivation { ... }, e o resultado é um conjunto de atributos opaco
  • No Guix, um pacote é um registro <package>, uma estrutura de dados transparente com campos nomeados que pode ser inspecionada, transformada e combinada com procedimentos padrão de Scheme
  • Como as definições de pacote no Guix são registros transparentes, e não funções opacas, é possível fazer inspeção e transformação de forma programática sem ferramentas especiais
  • No Guix, como os pacotes são dados, é fácil realizar reescritas de grafos
  • No Guix, package-input-rewriting pode expressar a tarefa de percorrer todo o grafo de dependências e substituir perl por perl-minimal
  • A palavra-chave inherit do Guix redefine um pacote herdando todos os campos de coreutils e sobrescrevendo apenas os campos especificados
  • O Nix tem overlays com propósito semelhante, mas, por causa da interface de funções opacas, inspecionar e transformar é mais difícil e a usabilidade é inferior

Atualizações de segurança, bootstrap e autenticação

  • O grafting do Guix permite aplicar atualizações de segurança na árvore de dependências sem recompilar todos os pacotes dependentes
  • Quando há uma vulnerabilidade em bibliotecas de baixo nível como a glibc, o Guix pode reescrever os caminhos do repositório para substituí-las por versões corrigidas
  • O Nix recompila tudo em cenários de atualização de segurança, e em árvores grandes de dependências o tempo de build pode diferir em horas
  • O Guix dá forte ênfase ao bootstrap baseado em código-fonte, permitindo construir o sistema inteiro a partir de uma pequena base de confiança
  • A cadeia de bootstrap do Guix começa com um montador hexadecimal de cerca de 500 bytes, passa pelo compilador C mes escrito em Scheme, pelo tcc e chega ao toolchain GNU completo
  • O projeto bootstrappable builds trata dos detalhes completos de bootstrap a partir do código-fonte
  • O Nix depende de mais sementes binárias do que o Guix
  • Se não for possível auditar a cadeia de bootstrap, não é possível verificar completamente se o sistema foi realmente construído a partir do código-fonte pretendido; por isso, o bootstrap completo a partir do código-fonte é importante para confiança e verificabilidade
  • Os channels do Guix têm suporte nativo a autenticação criptográfica
  • Um channel do Guix especifica uma “introduction” composta por um commit específico e sua assinatura Ed25519, e o Guix verifica toda a cadeia de assinaturas desde essa introduction até o commit atual
  • Flakes usa HTTPS e a infraestrutura do GitHub como modelo de confiança, o que é um modelo de segurança diferente da autenticação de channels via Ed25519 do Guix

Correspondências principais da tabela de resumo

  • Na declaração de dependências, Flakes usa inputs em flake.nix, e Guix usa channels.scm e .guix-channel
  • Na fixação de dependências, Flakes usa flake.lock automático por projeto, e Guix usa guix describe automático por usuário e channels.scm com commits definidos manualmente por projeto
  • A avaliação pura é imposta no modo flake e, no Guix, é uma característica inerente ao design
  • No esquema de saídas, Flakes usa um attrset estruturado em outputs, e Guix usa registros Scheme ad hoc
  • Para ambiente de desenvolvimento, Flakes usa devShells e nix develop, e Guix usa manifest.scm e guix shell
  • Para configuração do sistema, Flakes usa nixosConfigurations e o sistema de módulos, e Guix usa operating-system e um DAG de serviços
  • Na reprodutibilidade com um único comando, Flakes usa nix build github:foo/bar, e Guix usa a forma guix time-machine -C channels.scm -- build
  • Na fixação por projeto, Flakes faz isso automaticamente com flake.lock, e Guix faz manualmente com channels.scm contendo commits
  • Na explorabilidade, Flakes usa nix flake show, e Guix depende da inspeção de módulos Scheme
  • No modelo de pacotes, Flakes/Nix usa funções opacas, e Guix usa registros transparentes
  • No init system, Nix usa systemd, e Guix usa GNU Shepherd
  • Em atualizações de segurança, Nix recompila tudo, e Guix usa grafting rápido
  • Na confiança do bootstrap, Nix se baseia em sementes binárias, e Guix em bootstrap completo a partir do código-fonte
  • Em atualizações autenticadas, Flakes usa confiança em HTTPS/GitHub, e Guix usa autenticação de channels com Ed25519
  • Em suporte a FHS, Nix oferece buildFHSUserEnv, e Guix oferece --emulate-fhs
  • No suporte além de Linux, Nix se organiza em torno do nix-darwin para macOS, e Guix em torno do GNU Hurd
  • Quanto a ser exclusivamente software livre, Nix não é exclusivo e é configurável, enquanto Guix segue a FSDG

Conclusão

  • Flakes e Guix resolvem o mesmo tipo de problema — reprodutibilidade, gerenciamento de dependências e declaração de sistema — com filosofias de arquitetura diferentes
  • Flakes se aproxima de um recurso único, com um arquivo, um esquema, um arquivo de lock e um conjunto de convenções
  • Guix é uma combinação de ferramentas ortogonais, como channels para distribuição, manifests para ambientes, operating-system para configuração, guix time-machine para reprodutibilidade e registros Scheme para outras estruturas
  • Se você prefere uma forma padrão única, um único arquivo de entrada, um único esquema de saída e um único formato de lock, Flakes tende a ser a escolha natural
  • Se você prefere combinar ferramentas pequenas e independentes, aplicando ao gerenciamento de pacotes a filosofia Unix de fazer cada ferramenta fazer bem uma coisa, Guix tende a se encaixar melhor
  • Os dois ecossistemas evoluíram em torno da ideia de que o gerenciamento de pacotes deve ser funcional, declarativo e reprodutível, e estão levando essa mesma ideia adiante com implementações diferentes

1 comentários

 
GN⁺ 5 시간 전
Comentários do Lobste.rs
  • Este site é irritante demais para ler no celular: a fonte é um pouco pequena e ele continua atrapalhando toda vez que eu rolo a página
    Depois da primeira comparação, ficou impossível ler, porque ele ficava pulando de volta para o índice

    • Simplesmente não dá para ler. Fica indo e voltando como um ioiô. Era um dos textos que eu mais queria ler recentemente, então fiquei decepcionado com uma experiência de leitura extremamente frustrante
    • No desktop acontece a mesma coisa. É absurdo e parece que estragaram a acessibilidade de propósito
  • Mesmo depois de ler o texto, ainda não entendi bem como especificar e fixar as dependências de um projeto. Para distribuir e compartilhar, parece que você precisa procurar manualmente o hash de commit de cada dependência transitiva e colocar tudo em channels.scm
    O time-machine parece funcionar só com o conjunto de pacotes do Guix, e não com dependências fora da árvore
    Também dá para executar com bastante facilidade código de um ponto antigo do nixpkgs, como em nix run github:nixos/nixpkgs/<commit hash>#<package>
    O ponto peculiar do Guix é que ele não separa a versão da coleção de pacotes da versão do gerenciador de pacotes. Para executar pacotes antigos, você acaba executando também uma versão antiga do Guix, e eu não entendo por que alguém iria querer isso
    No texto, ele diz que em flakes é preciso encontrar commits manualmente para especificá-los, mas logo em seguida dá como exemplo um comando do Guix em que também é preciso especificar um commit. Em Nix flake também dá para sobrescrever a versão do nixpkgs com --override-input, mas isso fica feio, e esse é um dos pontos que o unflake tenta melhorar

    • Tenho menos experiência com Guix do que o autor, mas li bastante da documentação, então vou tentar responder algumas coisas
      Normalmente o fluxo é desenvolver em um ambiente dedicado do guix shell e, quando chega a hora de compartilhar, usar guix describe -f channels > channels.scm para registrar todos os hashes de commit em channels.scm
      Pela documentação de declaring channel dependencies, dá para especificar commits das dependências, mas não parece haver uma opção para verificar se, quando essa dependência por sua vez tem dependências, elas também estão fixadas em commits específicos
      A notação --commit= do time-machine vale para canais do Guix, mas com -C também é possível carregar canais adicionais a partir de um arquivo
      Isso tem a vantagem de não perder o histórico nem a reprodutibilidade, mesmo quando há mudanças incompatíveis no gerenciador de pacotes e nos registros de pacotes
    • Isso seria possível criando um índice reverso do nixpkgs: algo como dos commits X até Y do nixpkgs conterem a versão A de um determinado pacote
      Mas isso exigiria um checkout do nixpkgs para cada commit, então o custo inicial de montar isso seria muito alto. Depois de pronto, o custo de manutenção do índice deve ser baixo
  • Já avisei o coopi sobre o problema no site e sobre esta thread, então espero que seja corrigido logo
    Falando como alguém totalmente inclinado para o lado do Guix, também gostaria que o Guix tivesse um arquivo/diretório padrão como o flake.nix ou um diretório nix, onde tudo ficasse concentrado como no Nix, como o coopi comentou. Só que talvez isso seja impossível, porque para importar módulos Scheme é preciso apontar o caminho correto
    Como este post no Lobsters contém as coisas de que o autor fala, parece que as tags nix e lisp já seriam suficientes

    • Não me convence tirar linux. É o único kernel que os dois têm em comum :P Mas, como você disse, unix talvez realmente não combine
    • Também seria bom ter um tipo de dado estruturado para canais que ajudasse a inferir automaticamente o que um canal fornece, como nos flakes
      Por exemplo, algo assim:
      (channel
        (operating-systems
          (list my-vm))
        (services
          (list my-system-service)))
      
      E também seria bom um comando guix channel para ajudar a criar e lidar com novos canais
  • Fico curioso se o Guix também tem algo como .inputs.nixpkgs.follows do Nix flake para sobrescrever a fixação de dependências transitivas
    Além disso, boa parte da explicação do autor sobre Guix lembra o Nix anterior aos flakes: sem ponto de entrada padrão, estruturado em torno de canais etc. Só que no Guix há um sistema de formatos e uma linguagem de verdade, então esse mesmo padrão parece causar menos dor. Dá a impressão de uma história alternativa do Nix caso ele fosse melhor ou tivesse outra linguagem

    • Para que isso serve?
  • Fico hesitante em recomendar por causa dos problemas de usabilidade apontados em outros comentários. Eu não percebi porque uso NoScript, com JavaScript desativado por padrão
    Ainda assim, este texto apareceu exatamente na hora certa. Na empresa estamos indo mais na direção de usar bastante Nix e temos sofrido um pouco com flakes, e a explicação deste texto foi muito mais clara do que a das outras coisas que eu tinha lido antes

    • Segundo o Coopi, ele tenta seguir aprimoramento progressivo para que dê para ler mesmo sem JavaScript ou CSS; no lado do JavaScript ele estragou isso, mas pelo menos a filosofia estava funcionando. Agora, ao que parece, o JavaScript também já deve estar corrigido
  • Resposta do Coopi: ele fez uma mudança hoje de manhã, mas não conseguiu testar por causa do trabalho e descobriu que havia um problema no JavaScript

  • Este site é inutilizável no iOS mobile. Parece que a página carrega lá embaixo e em seguida rola imediatamente para cima; se eu desço mais de uma tela, alguma coisa é acionada e me joga para o topo de novo
    O modo de leitura funciona, mas aí se perde o destaque e o detalhamento visual original, que era bem bom

  • É válido dizer que o que os flakes fazem também pode ser feito com várias ferramentas do Guix, mas é preciso observar que o Nix já tinha — e ainda tem — ferramentas pequenas e ortogonais para resolver os mesmos problemas
    O que os flakes oferecem é um ponto de entrada padrão para projetos e o ecossistema que isso possibilita, como o registro. O próprio texto diz que essa parte não existe no Guix
    Usuários de Guix podem concluir que um ponto de entrada padrão não é necessário, e muitos usuários de Nix também chegaram a essa conclusão
    Mas dizer que um conjunto de ferramentas ortogonais consegue fazer o papel dos flakes soa parecido com afirmar que o FreeBSD não precisa de suporte a OCI porque dá para fazer tudo com jails. Isso perde o ponto de que a padronização viabiliza um ecossistema
    Tenho bastante interesse em Guix e até contribuí um pouco, mas gostaria de comparar por que compilar com guix time-machine junto com channels.scm demora tanto mais do que mudar a fixação de um flake e avaliar o Nix. Se fosse algo como 3 vezes mais lento, por exemplo passar de 5~10 segundos para 15~30 segundos, eu aceitaria, mas quando tentei não pareceu nem de longe ficar só nisso