Pipeline de pesquisa
Objetivo: executar bash pipeline/run_pipeline.sh a partir de um checkout limpo mais os dados brutos
data/ recria todos os conjuntos de dados processados, resultados de análises, relatórios e saídas do
manuscrito. Todo script que produz algo usado a jusante é chamado, em ordem de dependência, por algum
script sob pipeline/.
Estrutura
pipeline/
_common.sh # helpers compartilhados, importados por cada run_*.sh (não executado diretamente)
run_pipeline.sh # orquestrador principal: chama os scripts de estágio em ordem
run_preprocessing.sh # estágio: src/prepro/*.R -> output/prepro/
run_analyses.sh # estágio: src/analysis/*.R -> output/analysis/
run_reports.sh # estágio: src/reports/*.qmd -> output/reports/
run_manuscript.sh # estágio: src/manuscript/* -> output/manuscript/
run_script.sh # executa qualquer .R ou .qmd individual com o mesmo logging
Os nomes dos estágios seguem as pastas src/ do projeto (ex.: noh-survey usa src/manu/
e run_manu.sh). Adicione estágios apenas para pastas que existem; não crie estágios vazios.
Convenções
#!/usr/bin/env basheset -euo pipefailem todos os scripts.- Um comentário de cabeçalho em cada script: o que faz, a linha de uso
(
bash pipeline/<nome>.sh) e qual estágio deve ter sido executado primeiro (Requires ...). - Os scripts mudam para o diretório raiz do projeto via
_common.sh, para funcionar de qualquer diretório. Todos os caminhos internos são relativos à raiz do projeto. - Logging:
run_pipeline.shexportaPIPELINE_LOG_DIR=logs/run_pipeline_<timestamp>. Cada estágio cria${PIPELINE_LOG_DIR:-logs}/run_<estágio>_<timestamp>/, então os estágios aninham-se sob a execução do pipeline ou vão paralogs/quando executados individualmente. Cada script R / documento Quarto registra seu log em<nome>_<HH-MM-SS>.txt. - Em caso de falha,
run_r/render_qmdimprime o script que falhou, o caminho do seu log e as últimas 20 linhas do log, então para o pipeline inteiro. - Dentro de um estágio, agrupe as chamadas sob cabeçalhos
echo "=== Camada N: <motivo> ==="por profundidade de dependência. Coloque um comentário final em qualquer chamada cuja dependência não seja óbvia (# precisa de output/prepro/redcap-joined.rds). Dependências entre estágios têm seu próprio bloco rotulado (ex.: um script de pré-processamento que precisa de resultados de PCA vai no estágio de análises, após PCA). - Cada estágio executa
mkdir -pnos diretórios de saída para os quais escreve. - Quarto renderiza na pasta de origem, então
render_qmdmove o resultado paraoutput/. Use um loopfor qmd in src/reports/*.qmd(ignorando templates) quando todos os relatórios em uma pasta são renderizados da mesma forma. - Etapas lentas recebem um
echo "NOTE: ... pode levar muito tempo"antes delas. - Mantenha as chamadas explícitas, uma linha por script. Não descubra automaticamente scripts R com globs: a ordem é o grafo de dependências e deve ser legível.
Templates
Copie-os do diretório templates/ desta skill e preencha-os:
| Template | Torna-se |
|---|---|
_common.sh | pipeline/_common.sh (copie como está) |
run_pipeline.sh | pipeline/run_pipeline.sh |
run_stage.sh | um pipeline/run_<estágio>.sh para cada estágio |
run_script.sh | pipeline/run_script.sh (copie como está) |
_common.sh fornece:
init_log_dir <nome-do-estágio>: cria e defineLOG_DIRrun_r <script.R> [args...]: executa um script R, stdout+stderr para seu log (args são adicionados ao nome do log, para execuções parametrizadas como o loop de grupos do noh-survey)run_r_console <script.R> <arquivo-stdout>: stdout salvo como artefato (ex.:output/manuscript/<nome>-console.txt), stderr para o logrender_qmd <doc.qmd> <destino-dir-ou-arquivo> [args quarto...]: renderiza e move a saída; passe um caminho de arquivo como destino para renomeá-lo (ex.: um PDF por-P grupo:...)find_quarto: busca o Quarto incluído com RStudio/Positron como fallback
Fluxo de trabalho
1. Faça um levantamento do projeto
- Liste
src/(efns/,config/) e qualquerpipeline/existente. Sepipeline/existir, leia todos os scripts antes de alterar qualquer coisa e mantenha o estilo onde diferir dessas convenções (pergunte antes de migrar um pipeline estabelecido). - Leia o CLAUDE.md ou README do projeto para a ordem de execução declarada.
2. Determine a ordem de dependências
Para cada .R / .qmd em src/, descubra o que lê e escreve:
grep -nE 'readRDS|read_rds|read_csv|read_excel|read\.csv|load\(|fread|readMat|source\(' <arquivo>
grep -nE 'saveRDS|write_rds|write_csv|ggsave|save\(|writexl|write\.csv|pdf\(|png\(|tiff\(' <arquivo>
Associe cada leitura ao script que escreve aquele arquivo. Uma leitura sem produtor deve ser
entrada bruta em data/; se não for, sinalize (é uma etapa de pipeline ausente ou uma saída
que foi gerada manualmente). Atribua camadas: Camada 0 lê apenas data/;
Camada N lê saídas de camadas < N. Mostre ao usuário a ordem resultante para quaisquer casos
não óbvios antes de escrever scripts.
Ignore archive/, misc/, templates (*template*) e scripts de rascunho, a menos que o
usuário diga o contrário, e liste o que foi ignorado.
3. Escreva os scripts
Copie os templates, preencha os estágios e camadas, execute chmod +x pipeline/*.sh.
4. Verifique a cobertura e a sintaxe
bash <diretorio-desta-skill>/scripts/check_coverage.sh <raiz-do-projeto>
Isso executa bash -n e shellcheck (se instalado) em todos os scripts do pipeline, então lista
arquivos src/ que nenhum script do pipeline menciona pelo nome. Arquivos renderizados por um loop
com glob aparecem como não mencionados, então verifique-os manualmente. Cada arquivo restante é
adicionado ao pipeline ou confirmado como intencionalmente excluído.
5. Auditoria de reprodutibilidade
Varra src/ e relate (não corrija silenciosamente) qualquer um dos seguintes:
setwd(ou caminhos absolutos (/Users/,C:/,~/): quebram em outras máquinas- aleatoriedade (
sample(,rnorm(,boot,simr,set.seedausente) sem umset.seed() - código apenas interativo:
View(,file.choose(,readline(,browser( - saídas escritas fora de
output/(exceto o renderizar-e-depois-mover do Quarto) rm(list = ls()): esconde dependências faltantes quando os scripts são executados em uma única sessão
6. Execute
O pipeline completo pode levar muito tempo e sobrescreve output/, então pergunte antes de
executá-lo. Ofereça executar um único estágio ou run_script.sh em um arquivo primeiro. Para
verificar a reprodutibilidade a partir do zero, mova output/ para o lado (mv output output.bak),
não o exclua, então execute run_pipeline.sh e compare.
7. Documente
Adicione ou atualize uma seção "Executar o pipeline" no CLAUDE.md ou README do projeto: o comando único, o que cada estágio faz e como executar um script individual.
Adicionar um script a um pipeline existente
- Descubra o que o novo script lê (passo 2) e, portanto, em qual estágio e camada ele se encaixa.
- Adicione uma linha
run_rlá, com um comentário de dependência se não for óbvio. - Se suas saídas alimentam scripts posteriores, verifique se eles ainda estão em uma camada posterior.
- Execute
scripts/check_coverage.sh.