O que eu digo aqui pode ser aplicado a muitos programas que disponibilizam pacotes oficiais para Arch/Manjaro se você estiver disposto a experimentar (ou mesmo em outras distribuições cujos gerenciadores de pacotes suportem repositórios localizados dentro do disco).
Etapa 1 – repositório personalizado
A base do procedimento aqui, é fazer o pacman
buscar pacotes já dentro do seu sistema de arquivos. Há um mecanismo nele para isso, descrito em detalhes nessa página da Wiki.
O essencial é:
- Crie uma pasta vazia (ex:
/home/usuario/pasta
) em qualquer lugar do seu sistema. - Coloque o primeiro pacote do programa que você quer atualizar direto da fonte nessa pasta. Baixe-o manualmente, depois vamos automatizar esse processo. Digamos,
exemplo-1.0-1.pkg.tar.xz
. - Abra um terminal nessa pasta e rode
repo-add "meurepositorio.db.tar.xz" "exemplo-1.0-1.pkg.tar.xz"
- Seu repositório personalizado começou, e agora tem o primeiro pacote.
Para fazer o pacman buscar pacotes nele, edite /etc/pacman.conf
e acrescente:
[meurepositorio]
SigLevel = Optional TrustAll
Server = file:///home/usuario/pasta
Substitua:
-
meurepositorio
pelo nome do arquivo.db.tar.xz
(sem as extensões) que você criou no passo 3, -
/home/usuario/pasta
pelo caminho da pasta criada no passo 1 (deixe ofile://
)
Agora, essa pasta vai ser um dos locais onde pacman busca atualizações durante o famoso pacman -Syu
, bastando rodar repo-add PACOTE meurepositorio.db.tar.xz
para “notificar” a existência do pacote.
Etapa 2, 3, 4, 5, etc. – Adicionando pacotes
Caso 1 – Pacotes com link fixo
Para isso, vamos pegar o exemplo do Zoom.
O link de download do Zoom para Arch Linux, se pegamos do site, é:
https://zoom.us/client/latest/zoom_x86_64.pkg.tar.xz
Pelo link, dá para ver que o link é relativo à latest
, ou sempre à última versão.
A maneira mais simples de criar garantir sua atualização seria o seguinte shell script:
#!/bin/bash
# Entrar na pasta do repositório.
# || exit 1 → se não for possível entrar na pasta (comando antes do ||), sair com erro.
cd /home/usuario/pasta || exit 1
# wget - baixar um arquivo, -O especificar a saída, -q não mostrar o progresso
# comando1 && comando2 - se o comando1 retornar sucesso, rodar o comando2
wget -qO "zoom.pkg.tar.xz" "https://zoom.us/client/latest/zoom_x86_64.pkg.tar.xz" &&
repo-add "meurepositorio.db.tar.xz" "zoom.pkg.tar.xz"
Com systemd-timers ou cron, é possível, por exemplo, rodar esse script a dia, mês ou semana. E o pacman
pode pegar arquivos baixados por ele durante o -Syu
.
O script como está até agora é um pouco “gastador”, (por exemplo, ele apenas baixa sem verificar se realmente há uma versão nova, e se houver alguma falha no download, o arquivo antigo será sobrescrito pela versão incompleta), mas é um começo.
Caso 2 – Extrair o link de um site com a lista de versões
Se você tiver uma página com a lista de versões do programa, dá para automatizar o procedimento de download com nossas clássicas ferramentas de terminal (grep
, head
, etc.), combinadas com o wget
(que eu apresentei lá em cima) e um extrator de informações (parser) de HTML (nesse exemplo vou usar o pup
, mas há também o htmlq
). Ou, se você preferir, Python. Ou se você é nostálgico pelos anos 90, perl
+ libwww
. Enfim, vou colocar a versão com ferramentas de terminal, usando de exemplo o Wine-TKG, mais especificamente a lista de versões:
A primeira etapa é obter o conteúdo da página, para extrair dele os links. Eu apresentei o wget
com a opção -O
lá em cima. Se colocar -
(em vez de um nome de arquivo) depois do O
, a saída do wget
vai para o terminal:
wget -qO - "https://github.com/Frogging-Family/wine-tkg-git/releases"
<!DOCTYPE html>
<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark">
<head>
<meta charset="utf-8">
<link rel="dns-prefetch" href="https://github.githubassets.com">
<link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
<link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
<link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
[... sério, muita coisa]
Do jeito que ele está agora, o link para o arquivo provavelmente está por aí no meio dessa bagunça. Talvez um outro comando facilite achar o link nela… É justamente o que um parser de HTML pode fazer, como o pup
que eu citei.
Usando o |
, podemos passar a saída do wget -qO -
para a entrada de outro comando, . Nesse caso, o pup
, com o parâmetro 'a attr{href}'
, extrai os links da página:
$ wget -qO - "https://github.com/Frogging-Family/wine-tkg-git/releases" | pup 'a attr{href}'
#start-of-content
https://github.com/
/join?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Freleases%2Findex&source=header-repo
/features
[....]
Ok, ainda tem um monte de coisa irrelevante. No entanto, podemos filtrar essa saída com com o grep
.
$ wget -qO - "https://github.com/Frogging-Family/wine-tkg-git/releases" | pup 'a attr{href}' | grep '.pkg.tar.zst'
/Frogging-Family/wine-tkg-git/releases/download/6.8.r0.g0f00e37c/wine-tkg-staging-fsync-git-6.8.r0.g0f00e37c-326-x86_64.pkg.tar.zst
/Frogging-Family/wine-tkg-git/releases/download/6.7.r0.gdeed76f3/wine-tkg-staging-fsync-git-6.7.r0.gdeed76f3-326-x86_64.pkg.tar.zst
/Frogging-Family/wine-tkg-git/releases/download/6.5.r1.g2e42e7d9/wine-tkg-staging-fsync-git-6.5.r1.g2e42e7d9-322-x86_64.pkg.tar.zst
/Frogging-Family/wine-tkg-git/releases/download/6.4.r0.g7ec998e1/wine-tkg-staging-fsync-git-6.4.r0.g7ec998e1-322-x86_64.pkg.tar.zst
Agora é só coisa relevante. Melhor ainda, vem na ordem que eles apareceram na página, na qual o primeiro é o mais novo. Para obter o primeiro, pode-se usar head -nX
pega as X primeiras linhas. Como queremos a 1ª, head -n1
:
$ wget -qO - "https://github.com/Frogging-Family/wine-tkg-git/releases" | pup 'a attr{href}' | grep '.pkg.tar.zst' | head -n1
/Frogging-Family/wine-tkg-git/releases/download/6.8.r0.g0f00e37c/wine-tkg-staging-fsync-git-6.8.r0.g0f00e37c-326-x86_64.pkg.tar.zst
Em alguns casos, como esse, o link vem com uma parte omitida. O problema é que o navegador sabe que tem que colocar https://github.com
no começo, mas nosso script não.
Contudo, dá para dizer isso para o script. Podemos armazenar a saída desse comando em uma variável no script, usando $()
, e então rodar um segundo wget tento como parâmetro "https://github.com/$VARIAVEL"
(ou seja, “https://github.com/ e $ubstitua essa parte com a VARIAVEL”):
#!/bin/bash
cd /home/usuario/pasta || exit 1
ARQUIVO=$(wget -qO - "https://github.com/Frogging-Family/wine-tkg-git/releases" | pup 'a attr{href}' | grep '.pkg.tar.zst' | head -n1)
wget -qO "wine-tkg.tar.xz" "https://github.com/$ARQUIVO" && repo-add "meurepositorio.db.tar.xz" "wine-tkg.tar.xz"
Novamente, com um temporizador, dá para rodar isso semanalmente ou mensalmente, garantido um nível de atualidade que rivaliza o Bomba Patch (apesar de isso ainda poder ter os mesmos defeitos do primeiro script).
Notas de rodapé
- Se você não tiver o comando Wget no seu sistema, mas tiver o
curl
, pode usar:-
curl -s [SITE]
em vez dewget -qO - [SITE]
-
curl -s -o [ARQUIVO] [SITE]
em vez dewget -qO [ARQUIVO] [SITE]
.
-
- Para esse tópico não ficar mais complicado do que já é, as sugestões para melhorar a eficiência (verificar versão, fazer backup da versão antiga antes de baixar a nova, etc.) ficam como um exercício para o leitor. Se houver um interesse, posso fazer um apêndice com como fazer isso.
- Quem é mais experiente no terminal viu várias “micromelhorias” que podem ser feitas nos exemplos que eu dei, como usar
grep -Fm1
, criar funções para automatizar partes repetidas, etc., mas isso pode ser aprendido em tutoriais mais gerais de shellscript. - Sei que o GitHub disponibiliza um arquivo JSON para obter as versões e links de downloads dos programas (e isso poderia ser utilizado no exemplo), mas não desejo o
jq
para muitas pessoas. Com um conhecimento adequado das APIs para analisar JSON e baixar arquivos em outras linguagens de programação, no entanto, é trivial fazer a mesma automação em outras linguagens, apenas utilizandosystem("repo-add \Q$pacote\E meurepositorio.db.tar.xz");
no final ou equivalente.