55import glob
66import gzip
77import curses
8+ from datetime import datetime
89from pygments import highlight
910from pygments .lexers import get_lexer_by_name
1011from pygments .formatters import get_formatter_by_name
1314from rich .console import Console
1415from rich .panel import Panel
1516from rich .prompt import Prompt
16- from rich .table import Table
1717from rich import print as rprint
1818from harpy .common .printing import harpy_table , print_error
1919from harpy .common .file_ops import is_gzip
@@ -43,7 +43,7 @@ def check_terminal_colors():
4343
4444def parse_file (infile : str ):
4545 '''
46- take an input file name, get the most recent by modificiation time, and print it via pygmentized less
46+ take a list of input file name, get the most recent by modificiation time, and print it via pygmentized less
4747 returns a string of the file that was viewed
4848 '''
4949 if not os .access (infile , os .R_OK ):
@@ -69,7 +69,8 @@ def _read_file(x: str):
6969 echo_via_pager (_read_file (infile ), color = n_colors > 0 )
7070 return infile
7171
72- @click .group (options_metavar = '' , context_settings = {"help_option_names" : ["-h" , "--help" ]})
72+ @click .group (options_metavar = '' )
73+ @click .help_option ('--help' , panel = "Workflow Options" , hidden = True )
7374def view ():
7475 """
7576 View a workflow's components
@@ -81,6 +82,7 @@ def view():
8182@click .command (no_args_is_help = True , context_settings = {"allow_interspersed_args" : False })
8283@click .option ("-e" , "--edit" , is_flag = True , default = False , help = "Open the config file in you system's default editor" )
8384@click .argument ('directory' , required = True , type = click .Path (exists = True , file_okay = False ), nargs = 1 )
85+ @click .help_option ('--help' , panel = "Workflow Options" , hidden = True )
8486def config (directory , edit ):
8587 """
8688 View/edit a workflow's config file
@@ -118,6 +120,7 @@ def config(directory, edit):
118120 )
119121
120122@click .command ()
123+ @click .help_option ('--help' , panel = "Workflow Options" , hidden = True )
121124@click .argument ('program' , required = False , type = str , nargs = 1 )
122125def environments (program ):
123126 """
@@ -156,23 +159,27 @@ def environments(program):
156159 console .print ()
157160 console .rule (i .removesuffix ('.yaml' ), style = "blue" )
158161 for d in deps .split ():
159- if program and program .lower () in d :
160- console .print (f"→ { d } " , style = "bold green" )
162+ if program :
163+ if program .lower () in d :
164+ console .print (f"→ { d } " , style = "bold blue" , highlight = False )
165+ else :
166+ console .print (f"- { d } " , style = "dim" , highlight = False )
161167 else :
162168 console .print (f"- { d } " , style = "default" , highlight = False )
163169 console .print ()
164170 return
165171
166172@click .command (no_args_is_help = True , context_settings = {"allow_interspersed_args" : False })
167- @click .option ("-c" , "--choose" , is_flag = True , default = False , help = "From one from all the logs " )
173+ @click .option ("-c" , "--choose" , is_flag = True , default = False , help = "List logs for user choice " )
168174@click .argument ('directory' , required = True , type = click .Path (exists = True , file_okay = False ), nargs = 1 )
169175def log (directory , choose ):
170176 """
171- View a workflow's last log file
177+ View a workflow's Snakemake log file
172178
173179 The log file contains everything Snakemake printed during runtime.
174- The only required input is the output folder previously created by Harpy where you can find
175- `.snakemake/log`. Navigate with the typical `less` keyboard bindings, e.g.:
180+ The only required input is an output folder created by Harpy where you can find
181+ `.snakemake/log`. Use `--choose` to pick from a list of all Snakemake logfiles in
182+ the `directory`. Navigate with the typical `less` keyboard bindings, e.g.:
176183
177184 | key | function |
178185 | :---------------------- | :------------------------- |
@@ -196,19 +203,23 @@ def log(directory, choose):
196203 )
197204
198205 files = sorted (files , key = os .path .getmtime , reverse = True )
199- if choose :
206+ if choose and len ( files ) > 1 :
200207 console = Console ()
201208 console .print ()
202- console .rule ('Snakemake Log Files' , style = "green" )
209+ # console.rule('Snakemake Log Files', style = "green")
203210 _tb = harpy_table ()
204- _tb .add_column ("Number" , justify = "left" , style = "bold green" , no_wrap = True )
205- _tb .add_column ("File" , justify = "left" )
211+ _tb .show_header = True
212+ _tb .add_column ("[bold green]#" , style = "bold green" , min_width = 2 )
213+ _tb .add_column ("[dim yellow]Last Modification" ,style = "dim yellow" )
214+ _tb .add_column ("Log File" , justify = "right" , no_wrap = True )
206215 for i ,j in enumerate (files ,1 ):
207- _tb .add_row (str (i ), os .path .basename (j ))
216+ filename = os .path .basename (j ).removesuffix (".snakemake.log" ) + "[dim].snakemake.log[/]"
217+ modtime = datetime .fromtimestamp (os .path .getmtime (j )).strftime ('%Y-%m-%d %H:%M' )
218+ _tb .add_row (str (i ), modtime , filename )
208219 console .print (_tb )
209- console .rule ('[dim]sorted newest (top) to oldest (bottom) [/]' , style = 'dim' )
220+ # console.rule('[dim]second column shows last modification time [/]', style = 'dim')
210221 selection = Prompt .ask (
211- "\n [bold blue]Select a log file by number[/]" ,
222+ "\n [bold blue]Select a log file by number ([bold green]#[/]) [/]" ,
212223 choices = list (str (i ) for i in range (1 ,len (files ) + 1 )),
213224 show_choices = False
214225 )
@@ -232,10 +243,11 @@ def log(directory, choose):
232243
233244@click .command (no_args_is_help = True , context_settings = {"allow_interspersed_args" : False })
234245@click .option ("-e" , "--edit" , is_flag = True , default = False , help = "Open the config file in you system's default editor" )
246+ @click .help_option ('--help' , panel = "Workflow Options" , hidden = True )
235247@click .argument ('directory' , required = True , type = click .Path (exists = True , file_okay = False ), nargs = 1 )
236248def snakefile (directory , edit ):
237249 """
238- View/edit a workflow's snakefile
250+ View/edit a workflow's Snakefile
239251
240252 The snakefile contains all the instructions for a workflow. The only required input is the output folder
241253 previously created by Harpy where you can find `workflow/workflow.smk`.
@@ -270,10 +282,11 @@ def snakefile(directory, edit):
270282
271283@click .command (no_args_is_help = True , context_settings = {"allow_interspersed_args" : False })
272284@click .option ("-e" , "--edit" , is_flag = True , default = False , help = "Open the config file in you system's default editor" )
285+ @click .help_option ('--help' , panel = "Workflow Options" , hidden = True )
273286@click .argument ('directory' , required = True , type = click .Path (exists = True , file_okay = False ), nargs = 1 )
274287def snakeparams (directory , edit ):
275288 """
276- View/edit a workflow's snakemake configurations
289+ View/edit a workflow's Snakemake configurations
277290
278291 The snakemake configuration file has the runtime parameters snakemake was invoked with (i.e.,
279292 computational specifics that don't impact your results). The only required input is the output folder
0 commit comments