Commits

David Wolever committed 966c42a

Changing stuff

Comments (0)

Files changed (6)

 # mental images scene files
 --type-set=mi=.mi
 --type-set=rst=.rst
-# Ignore virtualenvs
---ignore-dir=env
 --type-set=ssjs=.ssjs
 --type-set=json=.json
 --type-set=msl=.msl
 
 --follow
 --ignore-dir=env
+--ignore-dir=.env
 --ignore-dir=.tox
 # Please DO NOT EDIT or send patches for it.
 #
 # Please take a look at the source from
-# http://github.com/petdance/ack
+# https://github.com/petdance/ack
 # and submit patches against the individual files
 # that build ack.
 #
 use warnings;
 use strict;
 
-our $VERSION = '1.92';
+our $VERSION = '1.96';
 # Check http://betterthangrep.com/ for updates
 
 # These are all our globals.
         /^--th[pt]+t+$/ && App::Ack::_thpppt($_);
 
         # See if we want to ignore the environment. (Don't tell Al Gore.)
-        if ( $_ eq '--noenv' ) {
-            my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV );
-            delete @ENV{@keys};
-            $env_is_usable = 0;
+        if ( /^--(no)?env$/ ) {
+            $env_is_usable = defined $1 ? 0 : 1;
         }
     }
-    unshift( @ARGV, App::Ack::read_ackrc() ) if $env_is_usable;
+    if ( $env_is_usable ) {
+        unshift( @ARGV, App::Ack::read_ackrc() );
+    }
+    else {
+        my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV );
+        delete @ENV{@keys};
+    }
     App::Ack::load_colors();
 
     if ( exists $ENV{ACK_SWITCHES} ) {
             my $s = $nargs == 1 ? '' : 's';
             App::Ack::warn( "Ignoring $nargs argument$s on the command-line while acting as a filter." );
         }
+
         my $res = App::Ack::Resource::Basic->new( '-' );
-        App::Ack::search_resource( $res, $opt );
+        my $nmatches;
+        if ( $opt->{count} ) {
+            $nmatches = App::Ack::search_and_list( $res, $opt );
+        }
+        else {
+            # normal searching
+            $nmatches = App::Ack::search_resource( $res, $opt );
+        }
         $res->close();
-        exit 0;
+        App::Ack::exit_from_ack( $nmatches );
     }
 
     my $file_matching = $opt->{f} || $opt->{lines};
-    if ( !$file_matching ) {
-        @ARGV or App::Ack::die( 'No regular expression found.' );
+    if ( $file_matching ) {
+        App::Ack::die( "Can't specify both a regex ($opt->{regex}) and use one of --line, -f or -g." ) if $opt->{regex};
+    }
+    else {
         $opt->{regex} = App::Ack::build_regex( defined $opt->{regex} ? $opt->{regex} : shift @ARGV, $opt );
     }
 
         $nmatches = App::Ack::print_matches( $iter, $opt );
     }
     close $App::Ack::fh;
-    exit ($nmatches ? 0 : 1);
+    App::Ack::exit_from_ack( $nmatches );
 }
 
 =head1 NAME
 number of lines for each file that has lines matching.  Without
 B<-l>, some line counts may be zeroes.
 
+If combined with B<-h> (B<--no-filename>) ack outputs only one total count.
+
 =item B<--color>, B<--nocolor>
 
 B<--color> highlights the matching text.  B<--nocolor> supresses
 
 Sets the color to be used for matches.
 
+=item B<--color-lineno=I<color>>
+
+Sets the color to be used for line numbers.
+
 =item B<--column>
 
 Show the column number of the first match.  This is helpful for editors
 This applies only to the PATTERN, not to the regexes given for the B<-g>
 and B<-G> options.
 
-=item B<--[no]ignore-dir=DIRNAME>
+=item B<--[no]ignore-dir=I<DIRNAME>>
 
 Ignore directory (as CVS, .svn, etc are ignored). May be used multiple times
 to ignore multiple directories. For example, mason users may wish to include
 directories which would normally be ignored (perhaps to research the contents
 of F<.svn/props> directories).
 
+The I<DIRNAME> must always be a simple directory name. Nested directories like
+F<foo/bar> are NOT supported. You would need to specify B<--ignore-dir=foo> and
+then no files from any foo directory are taken into account by ack unless given
+explicitly on the command line.
+
 =item B<--line=I<NUM>>
 
 Only print line I<NUM> of each file. Multiple lines can be given with multiple
 
 Print this manual page.
 
-=item B<-n>
+=item B<-n>, B<--no-recurse>
 
 No descending into subdirectories.
 
 This applies only to the PATTERN, not to the regexes given for the B<-g>
 and B<-G> options.
 
+=item B<-r>, B<-R>, B<--recurse>
+
+Recurse into sub-directories. This is the default and just here for
+compatibility with grep. You can also use it for turning B<--no-recurse> off.
+
 =item B<--smart-case>, B<--no-smart-case>
 
 Ignore case in the search strings if PATTERN contains no uppercase
 Sorts the found files lexically.  Use this if you want your file
 listings to be deterministic between runs of I<ack>.
 
+=item B<--show-types>
+
+Outputs the filetypes that ack associates with each file.
+
+Works with B<-f> and B<-g> options.
+
 =item B<--thpppt>
 
 Display the all-important Bill The Cat logo.  Note that the exact
 
 See B<ACK_COLOR_FILENAME> for the color specifications.
 
+=item ACK_COLOR_LINENO
+
+Specifies the color of the line number when printed in B<--color>
+mode.  By default, it's "bold yellow".
+
+This option can also be set with B<--color-lineno>.
+
+See B<ACK_COLOR_FILENAME> for the color specifications.
+
 =item ACK_PAGER
 
 Specifies a pager program, such as C<more>, C<less> or C<most>, to which
 
 =head2 Why isn't ack finding a match in (some file)?
 
-Probably because it's of a type that ack doesn't recognize.
-
-ack's searching behavior is driven by filetype.  If ack doesn't
-know what kind of file it is, ack ignores it.
+Probably because it's of a type that ack doesn't recognize.  ack's
+searching behavior is driven by filetype.  B<If ack doesn't know
+what kind of file it is, ack ignores the file.>
+
+Use the C<-f> switch to see a list of files that ack will search
+for you.
 
 If you want ack to search files that it doesn't recognize, use the
 C<-a> switch.
 
 You can certainly use ack to select your files to update.  For
 example, to change all "foo" to "bar" in all PHP files, you can do
-this form the Unix shell:
+this from the Unix shell:
 
     $ perl -i -p -e's/foo/bar/g' $(ack -f --php)
 
 "ack-grep" when creating packages because there's already a package
 out there called "ack" that has nothing to do with this ack.
 
-I suggest you rename your ack-grep install to "ack" because one of
-the crucial benefits of ack is having a name that's so short and
-simple to type.
+I suggest you make a symlink named F<ack> that points to F<ack-grep>
+because one of the crucial benefits of ack is having a name that's
+so short and simple to type.
+
+To do that, run this with F<sudo> or as root:
+
+   ln -s /usr/bin/ack-grep /usr/bin/ack
+
+=head2 What does F<ack> mean?
+
+Nothing.  I wanted a name that was easy to type and that you could
+pronounce as a single syllable.
+
+=head2 Can I do multi-line regexes?
+
+No, ack does not support regexes that match multiple lines.  Doing
+so would require reading in the entire file at a time.
+
+If you want to see lines near your match, use the C<--A>, C<--B>
+and C<--C> switches for displaying context.
 
 =head1 AUTHOR
 
 =head1 BUGS
 
 Please report any bugs or feature requests to the issues list at
-Github: L<http://github.com/petdance/ack/issues>
+Github: L<https://github.com/petdance/ack/issues>
 
 =head1 ENHANCEMENTS
 
 ack users.  This includes requests for new filetypes.
 
 There is a list of enhancements I want to make to F<ack> in the ack
-issues list at Github: L<http://github.com/petdance/ack/issues>
+issues list at Github: L<https://github.com/petdance/ack/issues>
 
 Patches are always welcome, but patches with tests get the most
 attention.
 
 =item * The ack issues list at Github
 
-L<http://github.com/petdance/ack/issues>
+L<https://github.com/petdance/ack/issues>
 
 =item * AnnoCPAN: Annotated CPAN documentation
 
 
 =item * Git source repository
 
-L<http://github.com/petdance/ack>
+L<https://github.com/petdance/ack>
 
 =back
 
 How appropriate to have I<ack>nowledgements!
 
 Thanks to everyone who has contributed to ack in any way, including
+Matthew Wild,
+Scott Kyle,
+Nick Hooey,
+Bo Borgerson,
+Mark Szymanski,
+Marq Schneider,
 Packy Anderson,
 JR Boyens,
 Dan Sully,
 
 =head1 COPYRIGHT & LICENSE
 
-Copyright 2005-2009 Andy Lester.
+Copyright 2005-2011 Andy Lester.
 
 This program is free software; you can redistribute it and/or modify
-it under the terms of either:
-
-=over 4
-
-=item * the GNU General Public License as published by the Free
-Software Foundation; either version 1, or (at your option) any later
-version, or
-
-=item * the Artistic License version 2.0.
-
-=back
+it under the terms of the Artistic License v2.0.
 
 =cut
 package File::Next;
 our $VERSION;
 our $COPYRIGHT;
 BEGIN {
-    $VERSION = '1.92';
-    $COPYRIGHT = 'Copyright 2005-2009 Andy Lester.';
+    $VERSION = '1.96';
+    $COPYRIGHT = 'Copyright 2005-2011 Andy Lester.';
 }
 
 our $fh;
         '.hg'               => 'Mercurial',
         '.pc'               => 'quilt',
         '.svn'              => 'Subversion',
+        _MTN                => 'Monotone',
         blib                => 'Perl module building',
         CVS                 => 'CVS',
         RCS                 => 'RCS',
         binary      => q{Binary files, as defined by Perl's -B op (default: off)},
         cc          => [qw( c h xs )],
         cfmx        => [qw( cfc cfm cfml )],
+        clojure     => [qw( clj )],
         cpp         => [qw( cpp cc cxx m hpp hh h hxx )],
         csharp      => [qw( cs )],
         css         => [qw( css )],
+        delphi      => [qw( pas int dfm nfm dof dpk dproj groupproj bdsgroup bdsproj )],
         elisp       => [qw( el )],
         erlang      => [qw( erl hrl )],
         fortran     => [qw( f f77 f90 f95 f03 for ftn fpp )],
+        go          => [qw( go )],
+        groovy      => [qw( groovy gtmpl gpp grunit )],
         haskell     => [qw( hs lhs )],
         hh          => [qw( h )],
         html        => [qw( htm html shtml xhtml )],
         jsp         => [qw( jsp jspx jhtm jhtml )],
         lisp        => [qw( lisp lsp )],
         lua         => [qw( lua )],
-        make        => q{Makefiles},
+        make        => q{Makefiles (including *.mk and *.mak)},
         mason       => [qw( mas mhtml mpl mtxt )],
         objc        => [qw( m h )],
         objcpp      => [qw( mm h )],
         ocaml       => [qw( ml mli )],
         parrot      => [qw( pir pasm pmc ops pod pg tg )],
-        perl        => [qw( pl pm pod t )],
+        perl        => [qw( pl pm pm6 pod t )],
         php         => [qw( php phpt php3 php4 php5 phtml)],
         plone       => [qw( pt cpt metadata cpy py )],
         python      => [qw( py )],
         rake        => q{Rakefiles},
-        ruby        => [qw( rb rhtml rjs rxml erb rake )],
+        ruby        => [qw( rb rhtml rjs rxml erb rake spec )],
         scala       => [qw( scala )],
         scheme      => [qw( scm ss )],
         shell       => [qw( sh bash csh tcsh ksh zsh )],
         text        => q{Text files, as defined by Perl's -T op (default: off)},
         tt          => [qw( tt tt2 ttml )],
         vb          => [qw( bas cls frm ctl vb resx )],
+        verilog     => [qw( v vh sv )],
+        vhdl        => [qw( vhd vhdl )],
         vim         => [qw( vim )],
         yaml        => [qw( yaml yml )],
-        xml         => [qw( xml dtd xslt ent )],
+        xml         => [qw( xml dtd xsl xslt ent )],
     );
 
     while ( my ($type,$exts) = each %mappings ) {
             }
         }
     }
+    # add manually Makefile extensions
+    push @{$types{$_}}, 'make' for qw{ mk mak };
 
     # These have to be checked before any filehandle diddling.
     $output_to_pipe  = not -t *STDOUT;
             chomp @lines;
             close $fh or App::Ack::die( "$filename: $!\n" );
 
+            # get rid of leading and trailing whitespaces
+            for ( @lines ) {
+               s/^\s+//;
+               s/\s+$//;
+            }
+
             return @lines;
         }
     }
         'color|colour!'         => \$opt{color},
         'color-match=s'         => \$ENV{ACK_COLOR_MATCH},
         'color-filename=s'      => \$ENV{ACK_COLOR_FILENAME},
+        'color-lineno=s'        => \$ENV{ACK_COLOR_LINENO},
         'column!'               => \$opt{column},
         count                   => \$opt{count},
         'env!'                  => sub { }, # ignore this option, it is handled beforehand
         'h|no-filename'         => \$opt{h},
         'H|with-filename'       => \$opt{H},
         'i|ignore-case'         => \$opt{i},
+        'invert-file-match'     => \$opt{invert_file_match},
         'lines=s'               => sub { shift; my $val = shift; push @{$opt{lines}}, $val },
         'l|files-with-matches'  => \$opt{l},
         'L|files-without-matches' => sub { $opt{l} = $opt{v} = 1 },
         'passthru'              => \$opt{passthru},
         'print0'                => \$opt{print0},
         'Q|literal'             => \$opt{Q},
-        'r|R|recurse'           => sub {},
+        'r|R|recurse'           => sub { $opt{n} = 0 },
+        'show-types'            => \$opt{show_types},
         'smart-case!'           => \$opt{smart_case},
         'sort-files'            => \$opt{sort_files},
         'u|unrestricted'        => \$opt{u},
         'ignore-dirs=s'         => sub { shift; my $dir = remove_dir_sep( shift ); $ignore_dirs{$dir} = '--ignore-dirs' },
         'noignore-dirs=s'       => sub { shift; my $dir = remove_dir_sep( shift ); delete $ignore_dirs{$dir} },
 
-        'version'   => sub { print_version_statement(); exit 1; },
+        'version'   => sub { print_version_statement(); exit; },
         'help|?:s'  => sub { shift; show_help(@_); exit; },
         'help-types'=> sub { show_help_types(); exit; },
-        'man'       => sub { require Pod::Usage; Pod::Usage::pod2usage({-verbose => 2}); exit; },
+        'man'       => sub {
+            require Pod::Usage;
+            Pod::Usage::pod2usage({
+                -verbose => 2,
+                -exitval => 0,
+            });
+        },
 
         'type=s'    => sub {
             # Whatever --type=xxx they specify, set it manually in the hash
 
 
 sub ignoredir_filter {
-    return !exists $ignore_dirs{$_};
+    return !exists $ignore_dirs{$_} && !exists $ignore_dirs{$File::Next::dir};
 }
 
 
     return 'skipped' unless is_searchable( $basename );
 
     my $lc_basename = lc $basename;
-    return ('make',TEXT)        if $lc_basename eq 'makefile';
+    return ('make',TEXT)        if $lc_basename eq 'makefile' || $lc_basename eq 'gnumakefile';
     return ('rake','ruby',TEXT) if $lc_basename eq 'rakefile';
 
     # If there's an extension, look it up
     close $fh;
 
     if ( $header =~ /^#!/ ) {
-        return ($1,TEXT)       if $header =~ /\b(ruby|p(?:erl|hp|ython))\b/;
+        return ($1,TEXT)       if $header =~ /\b(ruby|lua|p(?:erl|hp|ython))-?(\d[\d.]*)?\b/;
         return ('shell',TEXT)  if $header =~ /\b(?:ba|t?c|k|z)?sh\b/;
     }
     else {
     return if $filename =~ m{^#.*#$}o;
     return if $filename =~ m{^core\.\d+$}o;
     return if $filename =~ m{[._].*\.swp$}o;
+    return if $filename =~ /[.-]min\.js$/;
 
     return 1;
 }
     my $str = shift;
     my $opt = shift;
 
+    defined $str or App::Ack::die( 'No regular expression found.' );
+
     $str = quotemeta( $str ) if $opt->{Q};
     if ( $opt->{w} ) {
         $str = "\\b$str" if $str =~ /^\w/;
                         output is redirected, or on Windows)
   --[no]colour          Same as --[no]color
   --color-filename=COLOR
-  --color-match=COLOR   Set the color for matches and filenames.
+  --color-match=COLOR
+  --color-lineno=COLOR  Set the color for filenames, matches, and line numbers.
   --flush               Flush output immediately, even when ack is used
                         non-interactively (when output goes to a pipe or
                         file).
                         The PATTERN must not be specified.
   -g REGEX              Same as -f, but only print files matching REGEX.
   --sort-files          Sort the found files lexically.
+  --invert-file-match   Print/search handle files that do not match -g/-G.
+  --show-types          Show which types each file has.
 
 File inclusion/exclusion:
   -a, --all-types       All file types searched;
     $ignore_dirs
 
   Files not checked for type:
-    /~\$/           - Unix backup files
-    /#.+#\$/        - Emacs swap files
+    /~\$/            - Unix backup files
+    /#.+#\$/         - Emacs swap files
     /[._].*\\.swp\$/ - Vi(m) swap files
-    /core\\.\\d+\$/   - core dumps
+    /core\\.\\d+\$/  - core dumps
+    /[.-]min\\.js\$/  - Minified javascript files
 
 Miscellaneous:
   --noenv               Ignore environment variables and ~/.ackrc
 
 $copyright
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of either: the GNU General Public License as
-published by the Free Software Foundation; or the Artistic License.
+This program is free software.  You may modify or distribute it
+under the terms of the Artistic License v2.0.
 END_OF_VERSION
 }
 
 
     $ENV{ACK_COLOR_MATCH}    ||= 'black on_yellow';
     $ENV{ACK_COLOR_FILENAME} ||= 'bold green';
+    $ENV{ACK_COLOR_LINENO}   ||= 'bold yellow';
 
     return;
 }
     my $nmatches = shift;
     my $ors = shift;
     my $count = shift;
-
-    App::Ack::print( $filename );
-    App::Ack::print( ':', $nmatches ) if $count;
+    my $show_filename = shift;
+
+    if ($show_filename) {
+        App::Ack::print( $filename );
+        App::Ack::print( ':', $nmatches ) if $count;
+    }
+    else {
+        App::Ack::print( $nmatches ) if $count;
+    }
     App::Ack::print( $ors );
 }
 
 sub print_count0 {
     my $filename = shift;
     my $ors = shift;
-
-    App::Ack::print( $filename, ':0', $ors );
+    my $show_filename = shift;
+
+    if ($show_filename) {
+        App::Ack::print( $filename, ':0', $ors );
+    }
+    else {
+        App::Ack::print( '0', $ors );
+    }
 }
 
 
 
         if ( $show_filename ) {
             App::Ack::print_filename($display_filename, $sep) if not $heading;
-            App::Ack::print_line_no($line_no, $sep);
+            my $display_line_no =
+                $color
+                    ? Term::ANSIColor::colored( $line_no, $ENV{ACK_COLOR_LINENO} )
+                    : $line_no;
+            App::Ack::print_line_no($display_line_no, $sep);
         }
 
         if ( $output_func ) {
 } # scope around search_resource() and print_match_or_context()
 
 
+TOTAL_COUNT_SCOPE: {
+my $total_count;
+
+sub get_total_count {
+    return $total_count;
+}
+
+sub reset_total_count {
+    $total_count = 0;
+}
+
 
 sub search_and_list {
     my $res = shift;
     my $nmatches = 0;
     my $count = $opt->{count};
     my $ors = $opt->{print0} ? "\0" : "\n"; # output record separator
+    my $show_filename = $opt->{show_filename};
 
     my $regex = qr/$opt->{regex}/;
 
         }
     }
 
-    if ( $nmatches ) {
-        App::Ack::print_count( $res->name, $nmatches, $ors, $count );
+    if ( $opt->{show_total} ) {
+        $total_count += $nmatches;
     }
-    elsif ( $count && !$opt->{l} ) {
-        App::Ack::print_count0( $res->name, $ors );
+    else {
+        if ( $nmatches ) {
+            App::Ack::print_count( $res->name, $nmatches, $ors, $count, $show_filename );
+        }
+        elsif ( $count && !$opt->{l} ) {
+            App::Ack::print_count0( $res->name, $ors, $show_filename );
+        }
     }
 
     return $nmatches ? 1 : 0;
 }   # search_and_list()
 
+} # scope around $total_count
+
 
 
 sub filetypes_supported_set {
 
     my $nmatches = 0;
     while ( defined ( my $file = $iter->() ) ) {
-        App::Ack::print $file, $ors;
+        App::Ack::print $file, $opt->{show_types} ? " => " . join( ',', filetypes( $file ) ) : (),  $ors;
         $nmatches++;
         last if $opt->{1};
     }
     my $iter = shift;
     my $opt = shift;
 
+    # if we have -l and only 1 file given on command line (this means
+    # show_filename is set to 0), we want to see the filename nevertheless
+    $opt->{show_filename} = 1 if $opt->{l};
+
+    $opt->{show_filename} = 0 if $opt->{h};
+    $opt->{show_filename} = 1 if $opt->{H};
+
+    # abuse options to hand in the show_total parameter to search_and_list
+    $opt->{show_total} = $opt->{count} && !$opt->{show_filename};
+    reset_total_count();
+
     my $nmatches = 0;
     while ( defined ( my $filename = $iter->() ) ) {
         my $repo = App::Ack::Repository::Basic->new( $filename );
         $repo->close();
     }
 
+    if ( $nmatches && $opt->{show_total} ) {
+        App::Ack::print_count('', get_total_count(), "\n", 1, 0  )
+    }
+
     return $nmatches;
 }
 
     return \@what;
 }
 
+sub _match {
+    my ( $target, $expression, $invert_flag ) = @_;
+
+    if ( $invert_flag ) {
+        return $target !~ $expression;
+    }
+    else {
+        return $target =~ $expression;
+    }
+}
 
 
 sub get_iterator {
 
     if ( $g_regex ) {
         $file_filter
-            = $opt->{u}   ? sub { $File::Next::name =~ /$g_regex/ } # XXX Maybe this should be a 1, no?
-            : $opt->{all} ? sub { $starting_point{ $File::Next::name } || ( $File::Next::name =~ /$g_regex/ && is_searchable( $_ ) ) }
-            :               sub { $starting_point{ $File::Next::name } || ( $File::Next::name =~ /$g_regex/ && is_interesting( @_ ) ) }
+            = $opt->{u}   ? sub { _match( $File::Next::name, qr/$g_regex/, $opt->{invert_file_match} ) }    # XXX Maybe this should be a 1, no?
+            : $opt->{all} ? sub { $starting_point{ $File::Next::name } || ( _match( $File::Next::name, qr/$g_regex/, $opt->{invert_file_match} ) && is_searchable( $_ ) ) }
+            :               sub { $starting_point{ $File::Next::name } || ( _match( $File::Next::name, qr/$g_regex/, $opt->{invert_file_match} ) && is_interesting( @ _) ) }
             ;
     }
     else {
 }
 
 
+sub exit_from_ack {
+    my $nmatches = shift;
+
+    my $rc = $nmatches ? 0 : 1;
+    exit $rc;
+}
+
+
 
 1; # End of App::Ack
 package App::Ack::Repository;
 --python-kinds=-vi
 --exclude=*env/*
 --exclude=*.tox/*
+--exclude=*min.js
 *.beam
 *.dump
 env/
+.env/
 *egg-info*

profile.laptop.local

 # see http://code.google.com/p/gevent/issues/detail?id=31
 export EVENT_NOKQUEUE=1
 
+alias shorty_psql="ssh -L8754:localhost:5432 shorty"
 let g:netrw_dirhistmax  =10
-let g:netrw_dirhist_cnt =5
-let g:netrw_dirhist_1='/Users/wolever/EnSi/repos/env/ensi/lib/python2.6/site-packages/django/forms'
-let g:netrw_dirhist_2='/Users/wolever/bin'
-let g:netrw_dirhist_3='/Users/wolever/EnSi/repos/pycommon/ensi_common/dirt'
-let g:netrw_dirhist_4='/Users/wolever/EnSi/repos/devops/embedded/config_template'
-let g:netrw_dirhist_5='/private/tmp/asdf'
+let g:netrw_dirhist_cnt =1
+let g:netrw_dirhist_1='/Users/wolever/EnSi/repos/backoffice/lumbo/msg_hub/tests'