Aion-Fs

 view release on metacpan or  search on metacpan

lib/Aion/Fs.pm  view on Meta::CPAN

}

# Вызывается для всех ошибок ввода-вывода
sub errorenter(&) {
	bless shift, "Aion::Fs::Find"
}

# Останавливает find будучи вызван с одного из его фильтров, errorenter или noenter
sub find_stop() {
	die bless \(my $stop = 1), "Aion::Fs::Find"
}

# Производит замену во всех указанных файлах. Возвращает файлы в которых замен не было
sub replace(&@) {
    my $fn = shift;
	my @noreplace; local $_; my $pkg = caller;
	my $aref = "$pkg\::a";	my $bref = "$pkg\::b";
    for $$aref (@_) {
		if(ref $$aref) { ($$aref, $$bref) = @$$aref } else { $$bref = ":utf8" }
        my $file = $_ = cat [$$aref, $$bref];
        $fn->();
		if($file ne $_) { lay [$$aref, $$bref], $_ } else { push @noreplace, $$aref if defined wantarray }
    }
	@noreplace
}

# Стирает все указанные файлы. Возвращает переданные файлы
sub erase(@) {
    -d? rmdir: unlink or die "erase ${\(-d? 'dir': 'file')} $_: $!" for @_;
	@_
}

# Переводит вилдкард в регулярку
sub wildcard(;$) {
	my ($wildcard) = @_;
	$wildcard = $_ if @_ == 0;
	$wildcard =~ s{
		(?<file> \*\*)
		| (?<path> \*)
		| (?<anyn> \?\? )
		| (?<any> \? )
		| (?<w1> \{ )
		| (?<w2> \} )
		| (?<comma> , )
		| .
	}{
		exists $+{file}? "[^/]*?":
		exists $+{path}? ".*?":
		exists $+{anyn}? "[^/]":
		exists $+{any}? ".":
		exists $+{w1}? "(":
		exists $+{w2}? ")":
		exists $+{comma}? "|":
		quotemeta $&
	}gxe;
	qr/^$wildcard$/ns
}

# Открывает файл на указанной строке в редакторе
use config EDITOR => "vscodium %p:%l";
sub goto_editor($$) {
	my ($path, $line) = @_;
	my $p = EDITOR;
	$p =~ s!%p!$path!;
	$p =~ s!%l!$line!;
	my $status = system $p;
	die "$path:$line --> $status" if $status;
	return;
}

# Из пакета в файловый путь
sub from_pkg(;$) {
	my ($pkg) = @_ == 0? $_: @_;
	$pkg =~ s!::!/!g;
	"$pkg.pm"
}

# Из файлового пути в пакет
sub to_pkg(;$) {
	my ($path) = @_ == 0? $_: @_;
	$path =~ s!\.\w+$!!;
	$path =~ s!/!::!g;
	$path
}

# Из пакета в файловый путь из @INC, пакет не подгружается
sub from_inc(;$) {
	my ($pkg) = @_ == 0? $_: @_;

	$pkg = from_pkg $pkg;

	for my $dir (@INC) {
		my $path = "$dir/$pkg";
		return $path if -f $path;
	}

	return;
}

# Из файлового пути в @INC в пакет
sub to_inc(;$) {
	my ($path) = @_ == 0? $_: @_;
	
	my $inc = join "|", map quotemeta, @INC;
	
	return to_pkg $' if $path =~ m!^(?:$inc)/!;

	return;
}

# Подключает модуль, если он ещё не подключён, и возвращает его
sub include(;$) {
	my ($pkg) = @_ == 0? $_: @_;
	return $pkg if $pkg->can("new") || $pkg->can("has");
	my $path = from_pkg $pkg;
	return $pkg if exists $INC{$path};
	require $path;
	$pkg
}

1;

lib/Aion/Fs.pm  view on Meta::CPAN

=head2 catonce (;$file)

Reads the file for the first time. Any subsequent attempt to read this file returns C<undef>. Used to insert js and css modules into the resulting file. Without a parameter, uses C<$_>.

=over

=item * C<$file> can contain arrays of two elements. The first is considered as a path, and the second as a layer. The default layer is C<:utf8>.

=item * If C<$file> is not specified, use C<$_>.

=back

	local $_ = "catonce.txt";
	lay "result";
	catonce  # -> "result"
	catonce  # -> undef
	
	eval { catonce[] }; $@ # ~> catonce not use ref path!

=head2 wildcard (;$wildcard)

Converts a file mask to a regular expression. Without a parameter, uses C<$_>.

=over

=item * C<**> - C<[^/]*>

=item * C<*> - C<.*>

=item * C<?> - C<.>

=item * C<??> - C<[^/]>

=item * C<{> - C<(>

=item * C<}> - C<)>

=item * C<,> - C<|>

=item * Other characters are escaped using C<quotemeta>.

=back

	wildcard "*.{pm,pl}"  # \> (?^usn:^.*?\.(pm|pl)$)
	wildcard "?_??_**"  # \> (?^usn:^._[^/]_[^/]*?$)

Used in filters of the C<find> function.

=head3 See also

=over

=item * L<File::Wildcard>.

=item * L<String::Wildcard::Bash>.

=item * L<Text::Glob> – C<glob_to_regex("*.{pm,pl}")>.

=back

=head2 goto_editor ($path, $line)

Opens the file in the editor from .config at the specified line. Defaults to C<vscodium %p:%l>.

.config.pm file:

	package config;
	
	config_module 'Aion::Fs' => {
	    EDITOR => 'echo %p:%l > ed.txt',
	};
	
	1;



	goto_editor "mypath", 10;
	cat "ed.txt"  # => mypath:10\n
	
	eval { goto_editor "`", 1 }; $@  # ~> `:1 --> 512

=head2 from_pkg (;$pkg)

Transfers the packet to the FS path. Without a parameter, uses C<$_>.

	from_pkg "Aion::Fs"  # => Aion/Fs.pm
	[map from_pkg, "Aion::Fs", "A::B::C"]  # --> ["Aion/Fs.pm", "A/B/C.pm"]

=head2 to_pkg (;$path)

Translates the path from the FS to the package. Without a parameter, uses C<$_>.

	to_pkg "Aion/Fs.pm"  # => Aion::Fs
	[map to_pkg, "Aion/Fs.md", "A/B/C.md"]  # --> ["Aion::Fs", "A::B::C"]

=head2 from_inc (;$pkg)

Translates the packet to the FS path in C<@INC>. The package file must exist in one of the C<@INC> paths. Without a parameter, uses C<$_>.

	from_inc "Aion::Fs" # -> $INC{'Aion/Fs.pm'}
	[map from_inc, "A::B::C", "Aion::Fs"]  # --> [$INC{'Aion/Fs.pm'}]
	
	from_inc "A::B::C" # -> undef

=head2 to_inc (;$path)

Translates the path from FS to C<@INC> into a package. Without a parameter, uses C<$_>.

	to_inc $INC{'Aion/Fs.pm'} # => Aion::Fs
	[map to_inc,"A/B/C.pm", $INC{'Aion/Fs.pm'}]  # --> ["Aion::Fs"]
	
	to_inc 'Aion/Fs.pm' # -> undef

=head2 ilay (;$path)

Creates a file descriptor. It knows how to close as soon as the last link to it disappears.

It also has a C<path> method, which returns the path to the file.

	my $test_file = "test_ilay_complete.txt";
	
	my $f = ilay $test_file;
	print $f "Line 1\n";
	print $f "Line 2\n";
	
	my $std = select $f; $| = 1; select $std;
	-s $f # -> 14
	
	$f->path # => test_ilay_complete.txt
	fileno($f) > 0 # -> 1
	
	undef $f;
	
	cat $test_file # => Line 1\nLine 2\n
	
	local $_ = [$test_file, ':raw'];
	my $f = ilay;
	
	my $str = "string";
	my $num = 42;



( run in 1.942 second using v1.01-cache-2.11-cpan-13bb782fe5a )