diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b8863e..d6f9a4b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,21 +1,22 @@ name: Release -run-name: Creating release tarball... on: push: tags: - "v*.*.*" jobs: - Create-Tarball: - runs-on: ubuntu-latest + build: + runs-on: ubuntu-22.04 + permissions: + id-token: "write" + contents: "write" steps: - - name: Checkout code - uses: actions/checkout@v5 - - name: Create tarball - run: git archive --format=tar.gz --prefix=jj/ -o jj.tgz HEAD + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Run `nix build` + run: nix build .#jiujitsu - name: Create release uses: softprops/action-gh-release@v2 with: - files: jj.tgz -permissions: - contents: write + files: result/bin/jj.com diff --git a/.gitignore b/.gitignore index 6f26811..e49dde4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,11 @@ *.log tmp/ +result/ +result .direnv/ .vagrant/ + +*.com* +*.tgz +.apperl/ diff --git a/README.md b/README.md index 32ddacc..5ba8104 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,49 @@ -# How to run while testing -Assuming you have all the perl dependencies installed, use: -`perl -I ./lib/ bin/jiujitsu` from the repository root. +# How to Use +```bash +wget https://github.com/luccdc/jj/releases/latest/download/jj.tgz +# OR +curl -LO https://github.com/luccdc/jj/releases/latest/download/jj.tgz +``` + +```bash +jj.com # Runs jiujitsu + +# Run as perl +cp jj.com perl +./perl + +# Run as perldoc +cp jj.com perldoc +./perldoc +``` + +# How to Develop +You'll need to have Nix installed to work on this. +If you're on Windows, either WSL or a virtual machine work perfectly. +Once you've got Linux, please: +1. [Install nix](https://nixos.org/download/) +2. Enable flakes by adding this line in `~/.config/nix/nix.conf`: + `experimental-features = nix-command flakes` +3. Reload the nix daemon with `systemctl`. + +Next, clone this repository: +(Make sure you're in an appropriate directory!) +``` shell +git clone git@github.com:luccdc/jj.git +cd jj +``` +From inside the repo, running `nix develop` should bring you into the nix development environment. +The first time you do this it may take a few minutes to load, that is normal. + +You can run intermediate work using `./bin/jj` from the repository root. + +## Producing Builds +While developing, you can run the builder with `apperlm configure && apperlm build`. +Note that these builds are _not_ produced cleanly. They will install cosmocc and perl separately the first time you run them. +In order to produce a release build, run `nix build .#jiujitsu`. In 45 minutes or so, **boom!** `jj.com` will appear in `result/bin/`. + +## Where to get dependencies from -# Where to get dependencies from Q: I need a library that does foo, don't want to write it myself. Where can I find it? A: CPAN! Check this list of high-quality tools: @@ -10,14 +51,21 @@ A: CPAN! Check this list of high-quality tools: Or search for it: - https://metacpan.org -# How to add a new Perl package to Nix +Once you have a good dependency in mind, [add it to nix](#how-to-add-a-new-perl-package-to-nix). + +## How to add a new Perl package to Nix 1. Find the package you want to add on [CPAN](https://metacpan.org/search) -2. Search [nixpkgs](https://search.nixos.org/packages?channel=unstable) for a matching perl540Package to add inside the `perl540.withPackages` expression. +2. Search [nixpkgs](https://search.nixos.org/packages?channel=unstable) for a matching perl540Package. 3. No dice? Generate the package with the `./nix/nix-generate-from-cpan.pl` script: `nix-generate-from-cpan.pl ` -4. Add the resulting expression into the `let`-expression in `nix/perl.nix`, and add the name to the final list. + - Add the resulting expression into the `let`-expression in `nix/perl.nix`, and add the name to the final object. +4. Add your package to the perlDeps list. + If you got it from nixpkgs, just the name please. + If you generated it, prefix the name with `generatedPerlPackages`. # Argument Parsing +**NOTICE: This crappy argparser will shortly be replaced with something better.** + Argument parsing uses the [Arguments](./lib/LUCCDC/jiujitsu/Util/Arguments.pm) module. A parser is a closure that can be called on a string representing the command-line. Each parser takes two arguments: @@ -48,6 +96,5 @@ The above exemplifies the creation and use of a parser. A parser closure will return a hash of the arguments, keyed to the names of options. If it encounters a subcommand, it will run that command and exit instead of returning. -# Packaging Options -- https://metacpan.org/pod/App::FatPacker -- https://metacpan.org/pod/pp +# Related Projects +Check out [jj-rs](https://github.com/luccdc/jj-rs/), our sister project and sometime-competing implementation, written by the legendary Andrew Rioux. diff --git a/apperl-project.json b/apperl-project.json new file mode 100644 index 0000000..569ca0e --- /dev/null +++ b/apperl-project.json @@ -0,0 +1,25 @@ +{ + "apperl_configs" : { + "jiujitsu" : { + "dest" : "jj.com", + "desc" : "description of this config", + "base" : "full", + "install_modules": [ + ".apperl/nix-links/Module-Path-0.19.tar.gz", + ".apperl/nix-links/File-Grep-0.02.tar.gz", + ".apperl/nix-links/strictures-2.000006.tar.gz" + ], + "zip_extra_files" : { + "__perllib__/LUCCDC" : [ + "lib/LUCCDC/Jiujitsu.pm", + "lib/LUCCDC/Jiujitsu/" + ], + "bin" : [ + "bin/jj" + ] + }, + "default_script" : "/zip/bin/jj" + } + }, + "defaultconfig" : "jiujitsu" +} diff --git a/bin/jiujitsu b/bin/jiujitsu deleted file mode 100755 index e0dd12d..0000000 --- a/bin/jiujitsu +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env perl - -## no critic -BEGIN { - our @path = split( m{/bin/(?:jj|jiujitsu)}xms, __FILE__ ); -} - -use lib "$path[0]/lib"; - -## yes critic - -use LUCCDC::Jiujitsu; -LUCCDC::Jiujitsu->run; diff --git a/bin/jj b/bin/jj deleted file mode 120000 index c10671b..0000000 --- a/bin/jj +++ /dev/null @@ -1 +0,0 @@ -jiujitsu \ No newline at end of file diff --git a/bin/jj b/bin/jj new file mode 100755 index 0000000..1bbc4b5 --- /dev/null +++ b/bin/jj @@ -0,0 +1,3 @@ +#!/usr/bin/env perl +use LUCCDC::Jiujitsu; +LUCCDC::Jiujitsu->run; diff --git a/flake.lock b/flake.lock index e540b82..edf3f3f 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,18 @@ { "nodes": { + "cosmo": { + "flake": false, + "locked": { + "lastModified": 1716786888, + "narHash": "sha256-Ljyc0Jr7luKbLT7SEzm7lOhMm4gmJTfPHvYn5AhHCm8=", + "type": "tarball", + "url": "https://cosmo.zip/pub/cosmocc/cosmocc-3.3.10.zip" + }, + "original": { + "type": "tarball", + "url": "https://cosmo.zip/pub/cosmocc/cosmocc-3.3.10.zip" + } + }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -49,10 +62,24 @@ "type": "github" } }, + "perlSrc": { + "flake": false, + "locked": { + "narHash": "sha256-V8a6oHgn1cR70Hznn5znKMRb6gwOLE3z9WdSWYKH+E4=", + "type": "file", + "url": "https://github.com/Perl/perl5/archive/refs/tags/v5.36.3.tar.gz" + }, + "original": { + "type": "file", + "url": "https://github.com/Perl/perl5/archive/refs/tags/v5.36.3.tar.gz" + } + }, "root": { "inputs": { + "cosmo": "cosmo", "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "perlSrc": "perlSrc" } } }, diff --git a/flake.nix b/flake.nix index 9e52e37..e65fa45 100644 --- a/flake.nix +++ b/flake.nix @@ -4,59 +4,144 @@ inputs = { flake-parts.url = "github:hercules-ci/flake-parts"; nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + cosmo = { + url = "https://cosmo.zip/pub/cosmocc/cosmocc-3.3.10.zip"; + flake = false; + }; + + perlSrc = { + url = "file+https://github.com/Perl/perl5/archive/refs/tags/v5.36.3.tar.gz"; + flake = false; + }; }; - outputs = inputs@{ flake-parts, self, ...}: + outputs = inputs@{ flake-parts, self, perlSrc, cosmo, ...}: flake-parts.lib.mkFlake { inherit inputs; } { - imports = [ - # To import a flake module - # 1. Add foo to inputs - # 2. Add foo as a parameter to the outputs function - # 3. Add here: foo.flakeModule - ]; - - - # Systems supported - systems = [ "x86_64-linux" "aarch64-linux" ]; - - perSystem = { config, pkgs, lib, system, ... }: { - _module.args.pkgs = import self.inputs.nixpkgs { - inherit system; - config.allowUnfreePredicate = pkg: - builtins.elem (lib.getName pkg) [ - "vagrant" - ]; - }; - - devShells.default = - let - generatedPerlPackages = import ./nix/perl.nix {inherit pkgs lib;}; + imports = []; + + systems = [ "x86_64-linux" ]; + + perSystem = { config, pkgs, lib, system, ... }: + let + generatedPerlPackages = import ./nix/perl.nix {inherit pkgs lib;}; + + # + # NOTE: ADD NEW PERL PACKAGES HERE + # + # In nixpkgs? Just the name: `ModulePath` + # Generated from CPAN? Use `generatedPerlPackages.ModulePath` + # Obviously replace `ModulePath` with the name of your package. + perlDeps = with pkgs.perl540Packages; [ + ModulePath + FileGrep + strictures + ]; + + apperl-link = pkgs.writeShellScriptBin "apperl-link" '' +rm -fr ./.apperl/nix-links && echo "Removing previous links directory..." +mkdir -p ./.apperl/nix-links && echo "Creating links directory..." +echo -e "Creating links to CPAN sources...\ninstall_modules entries:" +${lib.concatMapStringsSep "\n" (p: ''ln -s ${toString p.out.src} ./.apperl/nix-links/${p.pname}-${p.version}.tar.gz + echo -e '\t".apperl/nix-links/${p.pname}-${p.version}.tar.gz"','') perlDeps} +''; + + jiujitsu = let + perlUrl = "file+https://github.com/Perl/perl5/archive/refs/tags/v5.36.3.tar.gz"; + apperl-project = lib.recursiveUpdate (lib.importJSON ./apperl-project.json) { + apperl_configs.jiujitsu = { + perl_url = perlUrl; + }; + }; + + apperl-site.cosmocc = "${cosmo}"; in - pkgs.mkShell { + pkgs.stdenv.mkDerivation rec { + pname = "jiujitsu"; + src = ./.; + version = "0.1.0"; + + buildInputs = [ + apperl-link + pkgs.perl + generatedPerlPackages.PerlDistAPPerl + ]; + nativeBuildInputs = perlDeps; + + outputs = ["out"]; + + HOME = "./fake-home"; + + dontFixup = true; + + preConfigure = '' + mkdir -p $HOME/.config/apperl/ .apperl/o + cp ${(pkgs.writers.writeJSON "apperl-project.json" apperl-project)} ./apperl-project.json + cp ${(pkgs.writers.writeJSON "site.json" apperl-site)} $HOME/.config/apperl/site.json + cp ${perlSrc} .apperl/o/${baseNameOf apperl-project.apperl_configs.jiujitsu.perl_url} + apperl-link + ''; + + configurePhase = '' + runHook preConfigure + apperlm configure + ''; + + buildPhase = '' + apperlm build + ''; + + installPhase = '' + mkdir -p $out/bin + cp ./${apperl-project.apperl_configs.jiujitsu.dest} $out/bin + cp ./${apperl-project.apperl_configs.jiujitsu.dest}.dbg $out/bin + ''; + }; + + in + { + _module.args.pkgs = import self.inputs.nixpkgs { + inherit system; + config.allowUnfreePredicate = pkg: + builtins.elem (lib.getName pkg) [ + "vagrant" + ]; + }; + + packages = { + inherit jiujitsu; + }; + + devShells.default = pkgs.mkShell { name = "jiujitsu"; buildInputs = with pkgs; [ vagrant + + # CLI Tools perl - (pkgs.perl540.withPackages (p-pkgs: with p-pkgs; [ - PLS - TryTiny - ModulePath - CPANPLUS - FileGrep + perl540Packages.PerlCritic + perl540Packages.PLS + generatedPerlPackages.PerlDistAPPerl + apperl-link + + # Needed for the CPAN generator script + (perl540.withPackages(p-pkgs: with p-pkgs; [ AppFatPacker GetoptLongDescriptive LogLog4perl - perlcritic + Readonly + CPANPLUS ])) - ] ++ generatedPerlPackages; + + ] ++ perlDeps; # Local dev demands we extend PERL5LIB to include our local library. - # Will not work for flake builds. - # TODO Determine robust path-setting for final build. + # apperl-link ensures we can also run local builds. shellHook = '' export PERL5LIB="$(pwd)/lib/:$PERL5LIB" - ''; + apperl-link +''; }; - }; + }; }; } diff --git a/lib/strictures.pm b/lib/strictures.pm deleted file mode 100644 index 889700e..0000000 --- a/lib/strictures.pm +++ /dev/null @@ -1,561 +0,0 @@ -package strictures; - -use strict; -use warnings FATAL => 'all'; - -BEGIN { - *_PERL_LT_5_8_4 = ( "$]" < 5.008004 ) ? sub() { 1 } : sub() { 0 }; - - # goto &UNIVERSAL::VERSION usually works on 5.8, but fails on some ARM - # machines. Seems to always work on 5.10 though. - *_CAN_GOTO_VERSION = ( "$]" >= 5.010000 ) ? sub() { 1 } : sub() { 0 }; -} - -our $VERSION = '2.000006'; -$VERSION =~ tr/_//d; - -our @WARNING_CATEGORIES = grep { exists $warnings::Offsets{$_} } qw( - closure - chmod - deprecated - exiting - experimental - experimental::alpha_assertions - experimental::autoderef - experimental::bitwise - experimental::const_attr - experimental::declared_refs - experimental::lexical_subs - experimental::lexical_topic - experimental::postderef - experimental::private_use - experimental::re_strict - experimental::refaliasing - experimental::regex_sets - experimental::script_run - experimental::signatures - experimental::smartmatch - experimental::win32_perlio - glob - imprecision - io - closed - exec - layer - newline - pipe - syscalls - unopened - locale - misc - missing - numeric - once - overflow - pack - portable - recursion - redefine - redundant - regexp - severe - debugging - inplace - internal - malloc - shadow - signal - substr - syntax - ambiguous - bareword - digit - illegalproto - parenthesis - precedence - printf - prototype - qw - reserved - semicolon - taint - threads - uninitialized - umask - unpack - untie - utf8 - non_unicode - nonchar - surrogate - void - void_unusual - y2k -); - -sub VERSION { - { - no warnings; - local $@; - if ( defined $_[1] && eval { &UNIVERSAL::VERSION; 1 } ) { - $^H |= 0x20000 - unless _PERL_LT_5_8_4; - $^H{strictures_enable} = int $_[1]; - } - } - _CAN_GOTO_VERSION ? goto &UNIVERSAL::VERSION : &UNIVERSAL::VERSION; -} - -our %extra_load_states; - -our $Smells_Like_VCS; - -sub import { - my $class = shift; - my %opts = @_ == 1 ? %{ $_[0] } : @_; - if ( !exists $opts{version} ) { - $opts{version} = - exists $^H{strictures_enable} - ? delete $^H{strictures_enable} - : int $VERSION; - } - $opts{file} = (caller)[1]; - $class->_enable( \%opts ); -} - -sub _enable { - my ( $class, $opts ) = @_; - my $version = $opts->{version}; - $version = 'undef' - if !defined $version; - my $method = "_enable_$version"; - if ( !$class->can($method) ) { - require Carp; - Carp::croak("Major version specified as $version - not supported!"); - } - $class->$method($opts); -} - -sub _enable_1 { - my ( $class, $opts ) = @_; - strict->import; - warnings->import( FATAL => 'all' ); - - if ( _want_extra( $opts->{file} ) ) { - _load_extras(qw(indirect multidimensional bareword::filehandles)); - indirect->unimport(':fatal') - if $extra_load_states{indirect}; - multidimensional->unimport - if $extra_load_states{multidimensional}; - bareword::filehandles->unimport - if $extra_load_states{'bareword::filehandles'}; - } -} - -our @V2_NONFATAL = grep { exists $warnings::Offsets{$_} } ( - 'exec', # not safe to catch - 'recursion', # will be caught by other mechanisms - 'internal', # not safe to catch - 'malloc', # not safe to catch - 'newline', # stat on nonexistent file with a newline in it - 'experimental', # no reason for these to be fatal - 'deprecated', # unfortunately can't make these fatal - 'portable', # everything worked fine here, just may not elsewhere -); -our @V2_DISABLE = grep { exists $warnings::Offsets{$_} } ( - 'once' # triggers inconsistently, can't be fatalized -); - -sub _enable_2 { - my ( $class, $opts ) = @_; - strict->import; - warnings->import; - warnings->import( FATAL => @WARNING_CATEGORIES ); - warnings->unimport( FATAL => @V2_NONFATAL ); - warnings->import(@V2_NONFATAL); - warnings->unimport(@V2_DISABLE); - - if ( _want_extra( $opts->{file} ) ) { - _load_extras(qw(indirect multidimensional bareword::filehandles)); - indirect->unimport(':fatal') - if $extra_load_states{indirect}; - multidimensional->unimport - if $extra_load_states{multidimensional}; - bareword::filehandles->unimport - if $extra_load_states{'bareword::filehandles'}; - } -} - -sub _want_extra_env { - if ( exists $ENV{PERL_STRICTURES_EXTRA} ) { - if ( _PERL_LT_5_8_4 and $ENV{PERL_STRICTURES_EXTRA} ) { - die 'PERL_STRICTURES_EXTRA checks are not available on perls older' - . "than 5.8.4: please unset \$ENV{PERL_STRICTURES_EXTRA}\n"; - } - return $ENV{PERL_STRICTURES_EXTRA} ? 1 : 0; - } - return undef; -} - -sub _want_extra { - my $file = shift; - my $want_env = _want_extra_env(); - return $want_env - if defined $want_env; - return ( - !_PERL_LT_5_8_4 - and $file =~ /^(?:t|xt|lib|blib)[\\\/]/ - and defined $Smells_Like_VCS - ? $Smells_Like_VCS - : ( - $Smells_Like_VCS = !!( - -e '.git' || -e '.svn' || -e '.hg' - || -e '.bzr' - || ( - -e '../../dist.ini' - && ( -e '../../.git' - || -e '../../.svn' - || -e '../../.hg' - || -e '../../.bzr' ) - ) - ) - ) - ); -} - -sub _load_extras { - my @extras = @_; - my @failed; - foreach my $mod (@extras) { - next - if exists $extra_load_states{$mod}; - - $extra_load_states{$mod} = eval "require $mod; 1;" or do { - push @failed, $mod; - - #work around 5.8 require bug - ( my $file = $mod ) =~ s|::|/|g; - delete $INC{"${file}.pm"}; - }; - } - - if (@failed) { - my $failed = join ' ', @failed; - my $extras = join ' ', @extras; - print STDERR < 'all'; - use warnings NONFATAL => qw( - exec - recursion - internal - malloc - newline - experimental - deprecated - portable - ); - no warnings 'once'; - -except when called from a file which matches: - - (caller)[1] =~ /^(?:t|xt|lib|blib)[\\\/]/ - -and when either C<.git>, C<.svn>, C<.hg>, or C<.bzr> is present in the current -directory (with the intention of only forcing extra tests on the author side) --- or when C<.git>, C<.svn>, C<.hg>, or C<.bzr> is present two directories up -along with C (which would indicate we are in a C operation, -via L) -- or when the C environment variable -is set, in which case it also does the equivalent of - - no indirect 'fatal'; - no multidimensional; - no bareword::filehandles; - -Note that C may at some point add even more tests, with -only a minor version increase, but any changes to the effect of C in normal mode will involve a major version bump. - -If any of the extra testing modules are not present, L will -complain loudly, once, via C, and then shut up. But you really -should consider installing them, they're all great anti-footgun tools. - -=head1 DESCRIPTION - -I've been writing the equivalent of this module at the top of my code for -about a year now. I figured it was time to make it shorter. - -Things like the importer in C don't help me because they turn -warnings on but don't make them fatal -- which from my point of view is -useless because I want an exception to tell me my code isn't warnings-clean. - -Any time I see a warning from my code, that indicates a mistake. - -Any time my code encounters a mistake, I want a crash -- not spew to STDERR -and then unknown (and probably undesired) subsequent behaviour. - -I also want to ensure that obvious coding mistakes, like indirect object -syntax (and not so obvious mistakes that cause things to accidentally compile -as such) get caught, but not at the cost of an XS dependency and not at the -cost of blowing things up on another machine. - -Therefore, L turns on additional checking, but only when it thinks -it's running in a test file in a VCS checkout -- although if this causes -undesired behaviour this can be overridden by setting the -C environment variable. - -If additional useful author side checks come to mind, I'll add them to the -C code path only -- this will result in a minor version -increase (e.g. 1.000000 to 1.001000 (1.1.0) or similar). Any fixes only to the -mechanism of this code will result in a sub-version increase (e.g. 1.000000 to -1.000001 (1.0.1)). - -=head1 CATEGORY SELECTIONS - -strictures does not enable fatal warnings for all categories. - -=over 4 - -=item exec - -Includes a warning that can cause your program to continue running -unintentionally after an internal fork. Not safe to fatalize. - -=item recursion - -Infinite recursion will end up overflowing the stack eventually anyway. - -=item internal - -Triggers deep within perl, in places that are not safe to trap. - -=item malloc - -Triggers deep within perl, in places that are not safe to trap. - -=item newline - -Includes a warning for using stat on a valid but suspect filename, ending in a -newline. - -=item experimental - -Experimental features are used intentionally. - -=item deprecated - -Deprecations will inherently be added to in the future in unexpected ways, -so making them fatal won't be reliable. - -=item portable - -Doesn't indicate an actual problem with the program, only that it may not -behave properly if run on a different machine. - -=item once - -Can't be fatalized. Also triggers very inconsistently, so we just disable it. - -=back - -=head1 VERSIONS - -Depending on the version of strictures requested, different warnings will be -enabled. If no specific version is requested, the current version's behavior -will be used. Versions can be requested using perl's standard mechanism: - - use strictures 2; - -Or, by passing in a C option: - - use strictures version => 2; - -=head2 VERSION 2 - -Equivalent to: - - use strict; - use warnings FATAL => 'all'; - use warnings NONFATAL => qw( - exec - recursion - internal - malloc - newline - experimental - deprecated - portable - ); - no warnings 'once'; - - # and if in dev mode: - no indirect 'fatal'; - no multidimensional; - no bareword::filehandles; - -Additionally, any warnings created by modules using L or -C will not be fatalized. - -=head2 VERSION 1 - -Equivalent to: - - use strict; - use warnings FATAL => 'all'; - # and if in dev mode: - no indirect 'fatal'; - no multidimensional; - no bareword::filehandles; - -=head1 METHODS - -=head2 import - -This method does the setup work described above in L. Optionally -accepts a C option to request a specific version's behavior. - -=head2 VERSION - -This method traps the C<< strictures->VERSION(1) >> call produced by a use line -with a version number on it and does the version check. - -=head1 EXTRA TESTING RATIONALE - -Every so often, somebody complains that they're deploying via C -and that they don't want L to enable itself in this case -- and that -setting C to 0 isn't acceptable (additional ways to -disable extra testing would be welcome but the discussion never seems to get -that far). - -In order to allow us to skip a couple of stages and get straight to a -productive conversation, here's my current rationale for turning the -extra testing on via a heuristic: - -The extra testing is all stuff that only ever blows up at compile time; -this is intentional. So the oft-raised concern that it's different code being -tested is only sort of the case -- none of the modules involved affect the -final optree to my knowledge, so the author gets some additional compile -time crashes which he/she then fixes, and the rest of the testing is -completely valid for all environments. - -The point of the extra testing -- especially C -- is to catch -mistakes that newbie users won't even realise are mistakes without -help. For example, - - foo { ... }; - -where foo is an & prototyped sub that you forgot to import -- this is -pernicious to track down since all I fine until it gets called -and you get a crash. Worse still, you can fail to have imported it due -to a circular require, at which point you have a load order dependent -bug which I've seen before now I show up in production due to tiny -differences between the production and the development environment. I wrote -L to explain -this particular problem before L itself existed. - -As such, in my experience so far L' extra testing has -I production versus development differences, not caused them. - -Additionally, L' policy is very much "try and provide as much -protection as possible for newbies -- who won't think about whether there's -an option to turn on or not" -- so having only the environment variable -is not sufficient to achieve that (I get to explain that you need to add -C at least once a week on freenode #perl -- newbies sometimes -completely skip steps because they don't understand that that step -is important). - -I make no claims that the heuristic is perfect -- it's already been evolved -significantly over time, especially for 1.004 where we changed things to -ensure it only fires on files in your checkout (rather than L-using -modules you happened to have installed, which was just silly). However, I -hope the above clarifies why a heuristic approach is not only necessary but -desirable from a point of view of providing new users with as much safety as -possible, and will allow any future discussion on the subject to focus on "how -do we minimise annoyance to people deploying from checkouts intentionally". - -=head1 SEE ALSO - -=over 4 - -=item * - -L - -=item * - -L - -=item * - -L - -=back - -=head1 COMMUNITY AND SUPPORT - -=head2 IRC channel - -irc.perl.org #toolchain - -(or bug 'mst' in query on there or freenode) - -=head2 Git repository - -Gitweb is on http://git.shadowcat.co.uk/ and the clone URL is: - - git clone git://git.shadowcat.co.uk/p5sagit/strictures.git - -The web interface to the repository is at: - - http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/strictures.git - -=head1 AUTHOR - -mst - Matt S. Trout (cpan:MSTROUT) - -=head1 CONTRIBUTORS - -Karen Etheridge (cpan:ETHER) - -Mithaldu - Christian Walde (cpan:MITHALDU) - -haarg - Graham Knop (cpan:HAARG) - -=head1 COPYRIGHT - -Copyright (c) 2010 the strictures L and L -as listed above. - -=head1 LICENSE - -This library is free software and may be distributed under the same terms -as perl itself. - -=cut diff --git a/nix/perl.nix b/nix/perl.nix index c02cbaa..aa8cf79 100644 --- a/nix/perl.nix +++ b/nix/perl.nix @@ -24,34 +24,6 @@ let }; }; - MooseXApp = buildPerlPackage { - pname = "MooseX-App"; - version = "1.43"; - src = fetchurl { - url = "mirror://cpan/authors/id/M/MA/MAROS/MooseX-App-1.43.tar.gz"; - hash = "sha256-w0YP6wM6R9V7PHbWZUfrf05ncjEnmMfoAp5qq6pnhIc="; - }; - buildInputs = [ - (withPackages (p-pkgs: with p-pkgs; [ - TestDifferences - TestException - TestWarn - TestDeep - TestMost TestNoWarnings - ])) - ]; - propagatedBuildInputs = [ - (withPackages (p-pkgs: with p-pkgs; [ - IOInteractive - ConfigAny Moose PodElemental namespaceautoclean - ])) - ]; - meta = { - description = "Write user-friendly command line apps with even less suffering"; - license = with lib.licenses; [ artistic1 gpl1Plus ]; - }; - }; - LinuxSystemd = buildPerlModule { pname = "Linux-Systemd"; version = "1.201600"; @@ -144,14 +116,31 @@ let }; }; + PerlDistAPPerl = buildPerlPackage { + pname = "Perl-Dist-APPerl"; + version = "0.6.1"; + src = fetchurl { + url = "mirror://cpan/authors/id/G/GA/GAHAYES/Perl-Dist-APPerl-v0.6.1.tar.gz"; + hash = "sha256-H455GwzKbVHpIJ2THq50rIBLPidkVrYMfYDRtZ0687M="; + }; + buildInputs = [ perl540Packages.FileShareDirInstall ]; + propagatedBuildInputs = [ pkgs.cosmocc pkgs.wget pkgs.zip perl540Packages.FileShareDir ]; + meta = { + homepage = "https://computoid.com/APPerl"; + description = "Actually Portable Perl"; + license = with lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + in -[ - GetoptEuclid - MooseXApp - LinuxSystemd - indirect - multidimensional - barewordfilehandles - NetDBus -] +{ + inherit + GetoptEuclid + LinuxSystemd + indirect + multidimensional + barewordfilehandles + NetDBus + PerlDistAPPerl; +}