Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
199 commits
Select commit Hold shift + click to select a range
a93a6c3
Fixed render_r1_r2 function(s) in Snakefiles
Oct 10, 2024
dfa2353
Merge branch 'master' into fix_406
daler Oct 11, 2024
d0a0300
add newline back in
daler Oct 13, 2024
f7e98ef
Merge pull request #413 from lcdb/fix_406
daler Oct 15, 2024
7d92555
Make strand_arg a param
b-full Oct 16, 2024
d168bb0
Merge pull request #415 from lcdb/fix_issue_405
daler Oct 19, 2024
b808d10
add Plodia interpunctella reference config (#417)
daler Oct 24, 2024
47b379a
Update plotting.R (#423)
njohnso6 Dec 4, 2024
aeca4c2
Change SRA fastq directory (#418)
b-full Dec 14, 2024
a2e5448
mambaforge -> miniforge
daler Jan 1, 2025
4487d90
latest ubuntu for testing
daler Jan 1, 2025
836fff0
https for downloading chainfile
daler Jan 1, 2025
09dedd7
noninteractive apt install
daler Jan 1, 2025
b6c663a
noninteractive apt install
daler Jan 1, 2025
2fc5d71
debug url
daler Jan 1, 2025
a470398
for test "external" data, do not do liftover
daler Jan 1, 2025
ed9161d
remove support for GAT
daler Jan 1, 2025
becdf21
GAT no longer used, remove from requirements
daler Jan 2, 2025
dfaec3e
don't pin python
daler Jan 2, 2025
b65f4cd
pin snakemake >8
daler Jan 2, 2025
0f81f07
update env.yml
daler Jan 2, 2025
f039b64
update snakefiles and lib to reflect changes in snakemake 8
daler Jan 2, 2025
bec163d
rm --bias for kallisto, which was causing segfaults
daler Jan 2, 2025
cc310fb
update test args -r --> --reason for snakemake 8
daler Jan 2, 2025
54514e9
rm --reason for snakemake 8
daler Jan 2, 2025
06c147b
disable colocalization workflow
daler Jan 3, 2025
bea0910
delete lots of stuff
daler Jan 3, 2025
060c2f8
add new references.smk
daler Jan 3, 2025
8bb7398
simplify config
daler Jan 3, 2025
79081fd
utils, common, and helpers are all now in utils
daler Jan 3, 2025
8337b98
cleanup patterns_targets
daler Jan 3, 2025
e8d16df
rnaseq workflow
daler Jan 3, 2025
36fd2e0
specify references dir from config
daler Jan 3, 2025
c321ed3
round of cleanup
daler Jan 3, 2025
32f43bc
better use of params
daler Jan 3, 2025
a9216b9
try moving utils.py to common.smk
daler Jan 4, 2025
300e73d
add strand_check and sra rules
daler Jan 4, 2025
407332e
mega refactor, still only partway done....
daler Jan 4, 2025
e3308bf
back to utils.py
daler Jan 7, 2025
1b62efc
rm libsizes table from multiqc
daler Jan 7, 2025
16d8489
use patterns
daler Jan 7, 2025
d6b512a
mv back to workflows/references/Snakefile
daler Jan 7, 2025
99f3f6b
fix params for bigwig
daler Jan 7, 2025
bf276c3
use slightly cleaner syntax
daler Jan 7, 2025
4328264
always put params directly before run/shell
daler Jan 7, 2025
5134c9e
run snakefmt on references
daler Jan 7, 2025
0b9beec
run snakefmt on rnaseq (and then re-add some comments that caused fai…
daler Jan 7, 2025
6968e4f
move wrappers to scripts
daler Jan 11, 2025
8013417
overhaul and simplify preprocessor
daler Jan 11, 2025
595eddf
add bed_to_bigbed as script
daler Jan 11, 2025
95cefea
add peakcallers to requirements.txt
daler Jan 11, 2025
c357763
clean up log handling for epic2
daler Jan 11, 2025
52ac28a
test settings overhaul
daler Jan 11, 2025
9024aa6
comment sampletable
daler Jan 11, 2025
2483b98
various rnaseq fixes
daler Jan 11, 2025
227646c
chipseq overhaul and simplification
daler Jan 11, 2025
4136207
clean up some tests
daler Jan 12, 2025
d7bb492
convert rrna table to script
daler Jan 12, 2025
66f5a11
fix test on preprocessor
daler Jan 12, 2025
bfdbf5e
updated env yaml
daler Jan 12, 2025
a466da0
fix import
daler Jan 12, 2025
eb68925
fix strand check
daler Jan 12, 2025
8f33026
split featurecounts
daler Jan 12, 2025
39209ce
all sorts of fixes and cleanup
daler Jan 12, 2025
155307a
sra for chipseq
daler Jan 12, 2025
fd1c1c3
clean out test suite
daler Jan 12, 2025
d322e33
add strandcheck back to snakefile
daler Jan 12, 2025
8b6b52a
don't use patterns any more
daler Jan 14, 2025
d5799fa
snakefmt cleanup
daler Jan 14, 2025
da2fc32
rrna_libsizes_table script avoids utils
daler Jan 19, 2025
b049ef6
use mem and disk rather than mem_mb and disk_mb
daler Jan 19, 2025
650e60f
convert to mem and disk in references
daler Jan 19, 2025
d5db4a5
spell out params fully in wrapper
daler Jan 19, 2025
b3a7d94
timestamped log file for slurm wrapper
daler Jan 19, 2025
aa437be
rm wrappers
daler Jan 20, 2025
9f00366
resources to strings
daler Jan 20, 2025
65d2e3b
rm chipseq patterns
daler Jan 20, 2025
3b57a27
update chipseq_trackhub.py
daler Jan 20, 2025
4e86e16
update rnaseq_trackhub.py
daler Jan 20, 2025
69376c9
rm colocalization workflow
daler Mar 29, 2025
1e50d55
rm references and colocalization tests
daler Mar 29, 2025
f37e666
rm rnaseq_patterns
daler Apr 2, 2025
6ab2807
move sra rule to separate file
daler Apr 2, 2025
091e215
move strand check to separate file
daler Apr 2, 2025
baf15c9
move params that don't depend on config back into rules
daler Apr 2, 2025
26d0834
support only star 1-pass mode
daler Apr 2, 2025
76affb6
updates to env.yml
daler Apr 2, 2025
0937a0a
add draft of decisions.rst
daler Oct 2, 2025
4a570e0
default to conda rather than mamba as front-end
daler Jul 10, 2025
e03f881
support additional packages during deployment
daler Jul 10, 2025
e86bbc2
pep8 on deploy.py
daler Jul 10, 2025
b1fc75e
support for setting additional-main from env var
daler Jul 14, 2025
6eb4633
deploy.py actually installs additional
daler Jul 30, 2025
93b89a6
try disabling pre-install
daler Oct 2, 2025
d2ebe75
don't copy test runner for references
daler Oct 3, 2025
22d414f
fix typo
daler Oct 4, 2025
e91b14e
new syntax style for markduplicates
daler Oct 4, 2025
a7d9737
refactor chipseq config
daler Oct 4, 2025
9ee9e06
invalidate cache
daler Oct 5, 2025
d567601
macs2 -> macs3
daler Oct 5, 2025
bee444e
rm params.extra for cutadapt
daler Oct 5, 2025
f8f7143
update env.yml
daler Oct 5, 2025
22e3f5d
move relevant references rules to rnaseq
daler Oct 5, 2025
0793fa3
convert bowtie2 to shell block
daler Oct 5, 2025
84bb39f
move strand check and sra to bottom
daler Oct 5, 2025
822afe2
simplify inputs
daler Oct 5, 2025
1c1f6f7
reflect changes to rule name
daler Oct 5, 2025
cff4e09
minor formatting
daler Oct 5, 2025
4122012
include additional .smk files when deploying
daler Oct 7, 2025
d71877f
update decision log
daler Oct 7, 2025
d4925c4
overhaul of rnaseq and chipseq; rm references
daler Oct 7, 2025
3b5a3be
fix paths in deploy
daler Oct 8, 2025
fc9af3a
references use params to properly trigger from config changes
daler Oct 8, 2025
82eb7c2
no longer mark references as temporary
daler Oct 8, 2025
99feb61
add featurecounts aggreation to multiqc input
daler Oct 8, 2025
523d3c3
rm kallisto from rnaseq
daler Oct 8, 2025
6548c60
disable results diagnostics by default
daler Oct 8, 2025
19be1d9
more updates to decision log
daler Oct 9, 2025
72d7757
rm kallisto throughout
daler Oct 9, 2025
a999bab
modify gene patterns test settings
daler Oct 9, 2025
f7996d5
sra & strand_check rules directly in respective snakefiles
daler Oct 9, 2025
ad55931
rm include sra.smk
daler Oct 9, 2025
7023a8d
rm *.smk from deployment
daler Oct 9, 2025
687af4f
rm strand_check
daler Oct 9, 2025
1e56148
rm more strandedness
daler Oct 9, 2025
a9d4677
rm now-irrelvant tests
daler Oct 9, 2025
0b2b3ce
rm more star 2pass tests
daler Oct 9, 2025
9902f64
rm another test
daler Oct 9, 2025
8ffc2ba
decision log on references
daler Oct 11, 2025
82f91a9
config file cleanup
daler Oct 11, 2025
c89b1eb
simplify references for rnaseq
daler Oct 11, 2025
7fa4b69
simplify references for chipseq
daler Oct 11, 2025
2989fcd
snakefmt on rnaseq
daler Oct 11, 2025
288c707
snakefmt on chipseq
daler Oct 11, 2025
7f281bc
update .gitignore
daler Oct 11, 2025
917c90f
hard-code peaks dir in chipseq_trackhub.py
daler Oct 11, 2025
e298d29
use .gz for those rules that can
daler Oct 11, 2025
e464267
temporarily name-sort PE bams for featurecounts
daler Oct 11, 2025
087e008
improve mappings.tsv generation
daler Oct 14, 2025
a2cc185
minor refactoring in utils.py
daler Oct 14, 2025
a4485ec
fasta -> genome and gtf -> annotation in configs
daler Oct 14, 2025
ba3c7ce
add faidx rule
daler Oct 14, 2025
8a32020
pep8 on postprocess.utils
daler Oct 14, 2025
69f3ed6
support gtf and fasta filtering on regexps
daler Oct 14, 2025
b4870cd
add reference config templates for human
daler Oct 14, 2025
40a64ff
verbose arg for filtering
daler Oct 14, 2025
999e122
updates to decision log
daler Oct 17, 2025
98a75b2
add gencode_m25 config for mouse
daler Oct 17, 2025
a0610ed
move postprocess.utils to postprocess
daler Oct 19, 2025
999fde2
match chipseq to rnaseq fasta->genome
daler Oct 19, 2025
854c362
minor cleanups in rnaseq snakefile
daler Oct 19, 2025
e6ef554
more simplification of references
daler Oct 19, 2025
b37edbf
decision log updates
daler Oct 19, 2025
a82e10c
add test config
daler Oct 19, 2025
2910b85
snakefmt
daler Oct 19, 2025
f2ddbe4
reconfigure tests
daler Oct 24, 2025
1291a23
rm lcdb-wf-test
daler Oct 24, 2025
5372cfc
fix some tests
daler Oct 24, 2025
0394f85
update decision log
daler Oct 24, 2025
0d009b0
another test fix
daler Oct 24, 2025
d693336
fix artifacts for rnaseq
daler Oct 26, 2025
da705f4
fix export path
daler Oct 27, 2025
828dcea
initial round of reference configs
daler Oct 27, 2025
db65bb7
ci/get-data.py: pep8, run from any dir, verbose mode
daler Oct 27, 2025
bc787f2
.fai as input for transcriptome fasta
daler Oct 27, 2025
1d1683e
unzipped references are marked temp()
daler Oct 27, 2025
d73109e
updates to decision log
daler Oct 27, 2025
919c458
gzip transcriptome fasta and mapping tsv
daler Oct 28, 2025
a3b6b33
pep8
daler Oct 28, 2025
1c698b2
include/exclude attributes in mappings
daler Oct 28, 2025
6b788ed
fix default postprocess
daler Oct 31, 2025
2b7084f
use configurable references dir
daler Oct 31, 2025
0ea7cfc
preflight checks
daler Oct 31, 2025
0ead4c3
rm no-longer used dependencies
daler Nov 4, 2025
dbb21a9
fill in label column with sample names if missing
daler Nov 4, 2025
a73eb63
rm plotfingerprint
daler Nov 4, 2025
383fb8b
clean up with prepare_*_sampletable functions
daler Nov 5, 2025
350f338
substantial cleanup in utils
daler Nov 5, 2025
b2370d2
update decision log:
daler Nov 5, 2025
04d5d69
trackhub scripts use new utils functions
daler Nov 5, 2025
8951b57
rm url check
daler Nov 5, 2025
b8fb369
typo
daler Nov 5, 2025
cb97ce1
improved sampletable handling
daler Nov 5, 2025
d9c3f78
fix trackhub imports
daler Nov 5, 2025
8f06eac
test SRA csv
daler Nov 5, 2025
a2cf9d8
df -> sampletable
daler Nov 5, 2025
fe999e2
use additional config for rnaseq trackhub
daler Nov 5, 2025
23164b1
update reference configs
daler Nov 6, 2025
5bc2b4b
initial overhaul of docs
daler Nov 6, 2025
4e839d6
a round of fixes in docs
daler Nov 6, 2025
9eee642
docs updates
daler Nov 6, 2025
c81adc8
config docs
daler Nov 6, 2025
284a3c7
decisions reorganization
daler Nov 6, 2025
be92aa6
chipseq: merged_label column,
daler Nov 7, 2025
1592976
no temp references
daler Nov 7, 2025
4dcb6a9
support for PE fastqc in multiqc (finally!)
daler Nov 7, 2025
6e45da4
lots of docs
daler Nov 7, 2025
1acc56e
snakefmt on chipseq
daler Nov 7, 2025
3983a28
decisions log for variant-calling
daler Nov 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 80 additions & 161 deletions .circleci/config.yml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ workflows/rnaseq/downstream/rnaseq.html
._*
Rplots.pdf
/lib/include/*

workflows/*/references

117 changes: 96 additions & 21 deletions ci/get-data.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,112 @@
#!/usr/bin/env python
import argparse
import os

from snakemake.shell import shell
from snakemake.utils import makedirs

shell.executable('/bin/bash')
BRANCH = 'master'
URL = 'https://github.com/lcdb/lcdb-test-data/blob/{0}/data/{{}}?raw=true'.format(BRANCH)
BRANCH = "master"
URL = "https://github.com/lcdb/lcdb-test-data/blob/{0}/data/{{}}?raw=true".format(
BRANCH
)

TOPLEVEL = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


def _download_file(fn, dest=None):
def _download_file(fn, dest=None, verbose=False):
url = URL.format(fn)
if dest is None:
dest = fn
dest = os.path.join(TOPLEVEL, dest)
makedirs(os.path.dirname(dest))
basename = os.path.basename(fn)
shell('wget -q -O- {url} > {dest}')
if not verbose:
q = "-q"
else:
q = ""
shell(f"wget {q} -O- {url} > {dest}")
if verbose:
print(f"Saved {dest}")
return dest


_download_file('rnaseq_samples/sample1/sample1.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample1.fq.gz')
_download_file('rnaseq_samples/sample2/sample2.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample2.fq.gz')
_download_file('rnaseq_samples/sample3/sample3.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample3.fq.gz')
_download_file('rnaseq_samples/sample4/sample4.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample4.fq.gz')
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--verbose", action="store_true", help="Be verbose when downloading")
args = ap.parse_args()

_download_file(
"rnaseq_samples/sample1/sample1.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample1.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample2/sample2.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample2.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample3/sample3.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample3.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample4/sample4.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample4.fq.gz",
args.verbose,
)

_download_file('rnaseq_samples/sample1/sample1.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample1PE_1.fq.gz')
_download_file('rnaseq_samples/sample1/sample1.small_R2.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample1PE_2.fq.gz')
_download_file('rnaseq_samples/sample2/sample2.small_R1.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample2PE_1.fq.gz')
_download_file('rnaseq_samples/sample2/sample2.small_R2.fastq.gz', 'workflows/rnaseq/data/example_data/rnaseq_sample2PE_2.fq.gz')
_download_file(
"rnaseq_samples/sample1/sample1.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample1PE_1.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample1/sample1.small_R2.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample1PE_2.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample2/sample2.small_R1.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample2PE_1.fq.gz",
args.verbose,
)
_download_file(
"rnaseq_samples/sample2/sample2.small_R2.fastq.gz",
"workflows/rnaseq/data/example_data/rnaseq_sample2PE_2.fq.gz",
args.verbose,
)

_download_file('chipseq_samples/input_1/input_1.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_input1.fq.gz')
_download_file('chipseq_samples/ip_1/ip_1.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_ip1.fq.gz')
_download_file('chipseq_samples/input_2/input_2.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_input2.fq.gz')
_download_file('chipseq_samples/ip_2/ip_2.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_ip2.fq.gz')
_download_file('chipseq_samples/ip_3/ip_3.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_ip3.fq.gz')
_download_file('chipseq_samples/ip_4/ip_4.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_ip4.fq.gz')
_download_file('chipseq_samples/input_3/input_3.tiny_R1.fastq.gz', 'workflows/chipseq/data/example_data/chipseq_input3.fq.gz')
_download_file(
"chipseq_samples/input_1/input_1.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_input1.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/ip_1/ip_1.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_ip1.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/input_2/input_2.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_input2.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/ip_2/ip_2.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_ip2.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/ip_3/ip_3.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_ip3.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/ip_4/ip_4.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_ip4.fq.gz",
args.verbose,
)
_download_file(
"chipseq_samples/input_3/input_3.tiny_R1.fastq.gz",
"workflows/chipseq/data/example_data/chipseq_input3.fq.gz",
args.verbose,
)
120 changes: 35 additions & 85 deletions ci/preprocessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,16 @@
in production. Rather than require users edit files to remove those
test-specific patterns, here we keep the test settings commented out and only
un-comment when running tests.

First, we look for any line that matches "# [test settings]" (case insensitive,
with optional surrounding spacing) and an optional signed integer. Any of these
would work:

>>> assert matches('# [test settings]')
>>> assert matches('#[test settings]')
>>> assert matches('# [ test settings ]')
>>> assert matches('# [ test settings -1]')
>>> assert matches('# [ test settings +2]')
>>> assert matches('# [ TEST SETTINGS +2]')
>>> assert matches('# [ TeSt SeTTiNgS +2 ]')

If a lines does not match, output it as-is.

If a line matches, then uncomment it. Specifically, remove the first "#" in the
line; if it was followed by exactly one space, then remove that too.

If a line matches and a signed integer was provided, then consider it
a relative location, and then comment-out the referred-to line. Example:

>>> preprocess('''
... use this for production
... # use this for tests # [test settings -1]
... '''.splitlines(True))
<BLANKLINE>
# use this for production
use this for tests # [test settings -1]
<BLANKLINE>

If the matched special string creates the first "#" in the line, then do
nothing to that line but still respect the relative locations. Useful for just
commenting out nearby lines for tests:

>>> preprocess('''
... # [TEST SETTINGS +1]
... comment out for testing'''.splitlines(True))
<BLANKLINE>
# [TEST SETTINGS +1]
# comment out for testing
"""


import re
regexp = re.compile(r'#\s?\[\s?test settings\s?(?P<rel>[-+]*\d)?\s*\]')

regexp = re.compile(r"#\s?\[\s?(enable|disable) for test\s?\]")

def matches(line):
return regexp.search(line.lower()) is not None

def is_commented(line):
return line.strip().startswith("#")


def comment_line(line):
Expand All @@ -66,87 +28,75 @@ def comment_line(line):
"""
x = []
for i, character in enumerate(line):
if character == ' ':
if character == " ":
x.append(character)
else:
break
x.append('# ')
x.append("# ")
x.extend(line[i:])
return ''.join(x)
return "".join(x)


def uncomment_line(line):
"""
Removes the first instance of "#" from a line; if it was followed by
exactly one space then remove that too.
exactly one space then remove that too . . . UNLESS the *only* comment is the
special character that triggers this behavior, in which case we do nothing.

>>> assert uncomment_line('# asdf') == 'asdf'
>>> assert uncomment_line('#asdf') == 'asdf'
>>> assert uncomment_line('# asdf # but this should be kept') == 'asdf # but this should be kept'
>>> assert uncomment_line('# asdf') == ' asdf'
>>> assert uncomment_line(' # asdf') == ' asdf'
>>> assert uncomment_line('do nothing') == 'do nothing'
>>> assert uncomment_line('do nothing # [disable for test]') == 'do nothing # [disable for test]'
>>> assert uncomment_line('#uncomment # [disable for test]') == 'uncomment # [disable for test]'
"""
first = line.find('#')
first = line.find("#")

# If the first comment is the one that flag the line, then do nothing.
# If the first comment is the one that flagged the line, then do nothing.
m = regexp.search(line.lower())
if m:
if m.start() == first:
return line

if line[first + 1] == ' ' and line[first + 2] != ' ':
pattern = '# '
if line[first + 1] == " " and line[first + 2] != " ":
pattern = "# "
else:
pattern = '#'
return line.replace(pattern, '', 1)
pattern = "#"
return line.replace(pattern, "", 1)


def preprocess(lines):
result = []

if isinstance(lines, str):
lines = [lines]

# These lists will keep track of whether a line should be changed. We need to
# create them ahead of time so that we can use relative indexing from line N to
# modify the state of lines N-1 or N+1
uncomment = [False for i in range(len(lines))]
comment = [False for i in range(len(lines))]

for i, line in enumerate(lines):
for line in lines:
m = regexp.search(line.lower())
if m:
# There as at least a "[ test settings ]", so remove comment
uncomment[i] = True

# Figure out if there was also a relative location to uncomment,
# and keep track of it in the `comment` list.
rel = m.group('rel')
if rel is not None:
rel = int(rel)
comment[i + rel] = True
if not m:
result.append(line)
continue

result = []
for (c, u, line) in zip(comment, uncomment, lines):
# E.g., in this situation, unclear what should happen:
#
# # [test settings]
# # [test settings -1]
#
if c and u:
raise ValueError("Line {0} is trying to be both commented and uncommented".format(line))
if c:
result.append(comment_line(line))
elif u:
action = m.group(1)
if action == "enable" and is_commented(line):
result.append(uncomment_line(line))
elif action == "disable" and not is_commented(line):
result.append(comment_line(line))
else:
result.append(line)
print(''.join(result))
raise ValueError(f"Inconsistent commenting and action:\n{line}")

print("".join(result))


if __name__ == "__main__":
import argparse

ap = argparse.ArgumentParser(usage=__doc__)
ap.add_argument('infile', help='Input file to modify. Modified file printed to stdout.')
ap.add_argument(
"infile", help="Input file to modify. Modified file printed to stdout."
)
args = ap.parse_args()
lines = open(args.infile).readlines()
preprocess(lines)
Loading