view release on metacpan or search on metacpan
lib/CPAN/Maker/Bootstrapper/ConfigReader.pm view on Meta::CPAN
=item C<perlcriticrc>
Path to a F<.perlcriticrc> configuration file. When set, enables
C<perlcritic> checking in the build system pattern rules.
=item C<llm-api-key-helper>
A shell command whose output is used as the LLM API key. Executed when
no key is passed directly and C<LLM_API_KEY> is not set in the environment.
The command should print the key and nothing else. The file it reads should
be chmod 600.
Example: cat ~/.ssh/anthropic-api-key
=back
=head1 METHODS
=head2 new
my $reader = CPAN::Maker::ConfigReader->new;
lib/CPAN/Maker/Bootstrapper/Role/Installer.pm view on Meta::CPAN
foreach (@manifest) {
die "ERROR: MANIFEST contains corrupted entry ($_)\n"
if $_ !~ m{\A[[:alnum:]][[:alnum:]._-]*(?:/[[:alnum:]][[:alnum:]._-]*)*\z}xsm;
die "ERROR: $_ is not found in the distribution. MANIFEST may be corrupted.\n"
if !-e "$dist_dir/$_";
if (/[.]mk$/xsm) {
die "ERROR: could not copy $dist_dir/$_ to $installdir/.includes/$_\n"
if !copy( "$dist_dir/$_", "$installdir/.includes/$_" );
chmod 0444, "$installdir/.includes/$_";
}
else {
die "ERROR: could not copy $dist_dir/$_ to $installdir/$_\n"
if !copy( "$dist_dir/$_", "$installdir/$_" );
}
}
# no need to check file existence, copy will fail above or rename will fail and be caught
rename "$installdir/Makefile.txt", "$installdir/Makefile"
or die "ERROR: error renaming $installdir/Makefile.txt to $installdir/Makefile: $OS_ERROR\n";
chmod 0444, "$installdir/Makefile";
chmod 0555, "$installdir/builder";
rename "$installdir/gitignore", "$installdir/.gitignore"
or die "ERROR: error renaming $installdir/gitignore to $installdir/.gitignore: $OS_ERROR\n";
return;
}
########################################################################
sub _import_files {
########################################################################
lib/CPAN/Maker/Bootstrapper/Role/Installer.pm view on Meta::CPAN
close $fh;
# copy scripts to bin
foreach my $s ( @{$scripts} ) {
my $dest = sprintf '%s/bin/%s.in', $installdir, basename($s);
$self->get_logger->debug( sprintf 'copying %s => %s', $s, $dest );
die "ERROR: error copying $s to $dest\n"
if !copy( $s, $dest );
chmod 0644, $dest; # remove -x
}
}
# copy tests to t
foreach my $t ( @{$tests} ) {
my $dest = sprintf '%s/t/%s', $installdir, basename($t);
$self->get_logger->debug( sprintf 'copying %s => %s', $t, $dest );
die "ERROR: error copying $t to $dest\n"
if !copy( $t, $dest );
chmod 0644, $dest; # make sure they are writable
}
# create sub directories and copy packages
foreach my $p ( keys %{$packages} ) {
my $primary = $self->_find_primary_package( $p, $packages->{$p} );
if ( !$primary ) {
warn "WARNING: could not determine primary package for $p...skipping.\n";
next;
lib/CPAN/Maker/Bootstrapper/Role/Installer.pm view on Meta::CPAN
my $lib_path = sprintf '%s/lib/%s', $installdir, dirname($path);
make_path($lib_path);
die "ERROR: could not create $lib_path\n" if !-d $lib_path;
my $dest = sprintf '%s/%s.in', $lib_path, basename($p);
die "ERROR: could not copy $p to $dest\n"
if !copy( $p, $dest );
chmod 0644, $dest; # make sure they are writable
}
return;
}
########################################################################
sub _create_resources_file {
########################################################################
my ( $self, $module_name, $installdir ) = @_;
release-notes.md view on Meta::CPAN
```bash
update_available=$(current="..." cpan="..." perl -Mversion -e \
'print version->parse($ENV{cpan}) > version->parse($ENV{current});')
```
**`make update` left managed files writable**
The `update` target was setting files writable before copying but
never restoring them to read-only afterward, leaving `Makefile` and
`.includes/*` writable after every update. The target now explicitly
runs `chmod -w` after all copies complete. The `post-update` loop also
applies `chmod -w` immediately after each file is copied rather than
before.
**`_install_files` not enforcing immutability**
The `bootstrapper` initializer set `.includes/*.mk` files to `0644`
(writable by owner), making it easy to accidentally edit a managed
file. Files are now installed as:
- `.includes/*.mk` - `0444` (read-only)
- `Makefile` - `0444` (read-only)
share/Makefile.txt view on Meta::CPAN
.DEFAULT_GOAL := all
all: update-available $(TARBALL) ## builds distribution tarball and dependencies
include .includes/perl.mk
bin/%.sh: bin/%.sh.in
$(NO_ECHO)sed -e 's/[@]PACKAGE_VERSION[@]/$(VERSION)/' \
-e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' < $< > $@; \
chmod +x $@
bin/%: bin/%.in
$(NO_ECHO)sed -e 's/[@]PACKAGE_VERSION[@]/$(VERSION)/' \
-e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' < $< > $@; \
chmod +x $@
.PHONY: quick
quick: ## quick build, turns off scanning, perltidy, perlcritic
$(NO_ECHO)$(MAKE) SCAN=off LINT=off
cpanfile: requires test-requires
$(NO_ECHO)if [[ -e requires ]] && [[ -e test-requires ]]; then \
all_requires=$$(mktemp); trap 'rm -f $$all_requires' EXIT; \
cp requires $$all_requires; \
cat test-requires >>$$all_requires; \
share/Makefile.txt view on Meta::CPAN
ChangeLog
$(TARBALL): $(DEPS) \
$(if $(tidy_on), $(PERL_MODULES:%=%.tdy) $(PERL_BIN_FILES:%=%.tdy)) \
$(if $(critic_on), $(PERL_MODULES:%=%.crit) $(PERL_BIN_FILES:%=%.crit))
$(MAKE_CPAN_DIST) -l $(LOG_LEVEL) -b $<
module.pm.tmpl:
$(NO_ECHO)if [[ -n "$(STUB)" ]]; then \
cp --preserve=all --update=none $(STUB) $@; \
chmod +w $@; \
else \
touch $@; \
fi; \
$(MODULE_PATH).in: | module.pm.tmpl
$(NO_ECHO)mkdir -p $$(dirname $@); \
test -e $@ || sed -e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' \
-e 's/[@]GIT_NAME[@]/$(GIT_NAME)/' \
-e 's/[@]GIT_EMAIL[@]/$(GIT_EMAIL)/' < module.pm.tmpl > $@
test.t.tmpl:
$(NO_ECHO)template=$$(perl -MFile::ShareDir=dist_file -e 'print dist_file(q{CPAN-Maker-Bootstrapper}, q{$@});' 2>/dev/null || true); \
if [[ -n "$$template" ]]; then \
cp $$template $@; \
else \
touch $@; \
fi; \
chmod 0644 $@
$(UNIT_TEST_NAME): | test.t.tmpl
$(NO_ECHO)sed -e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' < test.t.tmpl > $@
ifeq ($(wildcard README.md.in),)
# If README.md.in does NOT exist, use POD2MARKDOWN on the module
README.md: $(MODULE_PATH)
$(NO_ECHO)tmpfile=$$(mktemp); \
trap 'rm -f $$tmpfile' EXIT; \
echo "@TOC@" > $$tmpfile; \
share/Makefile.txt view on Meta::CPAN
ChangeLog:
$(NO_ECHO)test -e $@ || touch $@
buildspec.yml.tmpl:
$(NO_ECHO)template=$$(perl -MFile::ShareDir=dist_file -e 'print dist_file(q{CPAN-Maker-Bootstrapper}, q{$@});' 2>/dev/null || true); \
if [[ -n "$$template" ]]; then \
cp $$template $@; \
else \
touch $@; \
fi; \
chmod 0644 $@
buildspec.yml: | buildspec.yml.tmpl
$(NO_ECHO)buildspec=$$(mktemp); \
specfile="$(PROJECT_NAME)"; \
specfile="$${specfile,,}.yml"; \
if [[ -e "$$specfile" ]]; then \
share_files=" - $$specfile\n"; \
fi; \
trap 'rm -f $$buildspec' EXIT; \
sed -e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/g' \
share/Makefile.txt view on Meta::CPAN
.PHONY: workflow
workflow:
$(NO_ECHO)dist_dir=$$(perl -MFile::ShareDir=dist_dir -e 'print dist_dir(q{CPAN-Maker-Bootstrapper});' 2>/dev/null || true); \
if [[ -z "$$dist_dir" ]]; then \
echo >&2 "ERROR: could not determine CPAN::Maker::Bootstrapper share directory"; \
exit 1; \
fi; \
pwd=$$(pwd); \
cp $$dist_dir/builder $$pwd; \
chmod +x $$pwd/builder; \
build_requires="$$(mktemp)"; trap 'rm -f $$build_requires' EXIT; \
test -e build-requires || touch build-requires; \
cp build-requires $$build_requires; \
cat $$dist_dir/build-requires >>$$build_requires; \
sort -u $$build_requires > build-requires; \
mkdir -p $$pwd/.github/workflows; \
project_name="$(PROJECT_NAME)"; \
project_name="$${project_name,,}"; \
sed -e 's/CPAN::Maker::Bootstrapper/$(PROJECT_NAME)/' \
-e "s/cpan-maker-bootstrapper/$$project_name/" $$dist_dir/build.yml > $$pwd/.github/workflows/build.yml; \
share/perl.mk view on Meta::CPAN
%.pm: %.pm.in
$(NO_ECHO)module_tmp="$$(mktemp)"; \
local_cleanfiles="$$module_tmp"; \
trap 'rm -f $$local_cleanfiles' EXIT; \
sed -e 's/[@]PACKAGE_VERSION[@]/$(VERSION)/' \
-e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' $< > "$$module_tmp"; \
$(run_podextract); \
rm -f "$@"; \
cp "$$module_tmp" "$@"; \
chmod -w "$@"; \
$(if $(syntax_on),$(check_syntax_pm))
%.pl: %.pl.in
$(NO_ECHO)rm -f "$@"; \
sed -e 's/[@]PACKAGE_VERSION[@]/$(VERSION)/' \
-e 's/[@]MODULE_NAME[@]/$(MODULE_NAME)/' $< > "$@"; \
chmod +x "$@"; \
chmod -w "$@"; \
$(if $(syntax_on),$(check_syntax_pl))
# ------------------------------------------------------------------
# convenience targets
# ------------------------------------------------------------------
.PHONY: tidy critic lint
tidy: ## run perltidy on all source files
$(NO_ECHO)if [[ -z "$(PERLTIDYRC)" ]]; then \
share/update.mk view on Meta::CPAN
INCLUDES_DIR = .includes
.PHONY: post-update
post-update:
@mkdir -p $(INCLUDES_DIR); \
for f in $(MANAGED_FILES); do \
src="$(BOOTSTRAPPER_DIST_DIR)/$$f"; \
test -e "$$src" || continue; \
cp "$$src" "$(INCLUDES_DIR)/$$f"; \
chmod -w "$(INCLUDES_DIR)/$$f"; \
done; \
echo "Files updated. Review changes with: git diff"
.PHONY: update ## update managed project files from the installed bootstrapper
update:
@if [[ -e builder ]]; then \
chmod +w builder; \
cp $(BOOTSTRAPPER_DIST_DIR)/builder builder; \
chmod 0555 builder; \
fi; \
chmod +w Makefile; \
cp $(BOOTSTRAPPER_DIST_DIR)/Makefile.txt Makefile; \
chmod +w .includes/*; \
cp $(BOOTSTRAPPER_DIST_DIR)/update.mk .includes/; \
cp $(BOOTSTRAPPER_DIST_DIR)/upgrade.mk .includes/; \
$(MAKE) post-update; \
chmod -w Makefile .includes/*
.PHONY: update-available
update-available:
@if [[ -n "$(BOOTSTRAPPER_VERSION)" && "$(PROJECT_NAME)" != "CPAN-Maker-Bootstrapper" ]]; then \
dist=$$(cpanm --info -l /dev/null 2>/dev/null CPAN::Maker::Bootstrapper || true); \
if [[ "$$dist" =~ -([0-9.]+)\.tar\.gz$$ ]]; then \
version="$${BASH_REMATCH[1]}"; \
update_available=$$(current="$(BOOTSTRAPPER_VERSION)" cpan="$$version" perl -Mversion -e 'print version->parse($$ENV{cpan}) > version->parse($$ENV{current});'); \
if [[ -z "$$update_available" ]]; then \
echo "CPAN::Maker::Bootstrapper $$version is up-to-date."; \