From 5066fb72040b9c34f04d8f2237ae3dab04e5a997 Mon Sep 17 00:00:00 2001 From: Arthur Axel 'fREW' Schmidt Date: Wed, 20 Jul 2011 14:44:44 -0500 Subject: [PATCH] initial (working!) commit --- .gitignore | 1 + lib/Javascript/Dependancy/Manager.pm | 102 +++++++++++++++++++++++++++ t/basic.t | 26 +++++++ t/js-lib/A.js | 5 ++ t/js-lib/B.js | 5 ++ t/js-lib/C.js | 5 ++ t/js-lib/ext/ext-all-debug.js | 5 ++ t/js-lib/ext/ext-all.js | 1 + t/js-lib/ext/ext-core.js | 4 ++ 9 files changed, 154 insertions(+) create mode 100644 .gitignore create mode 100644 lib/Javascript/Dependancy/Manager.pm create mode 100644 t/basic.t create mode 100644 t/js-lib/A.js create mode 100644 t/js-lib/B.js create mode 100644 t/js-lib/C.js create mode 100644 t/js-lib/ext/ext-all-debug.js create mode 100644 t/js-lib/ext/ext-all.js create mode 100644 t/js-lib/ext/ext-core.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45d62d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.sw? diff --git a/lib/Javascript/Dependancy/Manager.pm b/lib/Javascript/Dependancy/Manager.pm new file mode 100644 index 0000000..9f32014 --- /dev/null +++ b/lib/Javascript/Dependancy/Manager.pm @@ -0,0 +1,102 @@ +package Javascript::Dependancy::Manager; + +use Moo; +use Sub::Quote; +use Tie::IxHash; + +has lib_dir => ( + is => 'ro', + required => 1, +); + +has recurse => ( + is => 'ro', + default => quote_sub q{ 0 }, +); + +has scan_files => ( + is => 'ro', + default => quote_sub q{ 1 }, +); + +has _scanned_files => ( + is => 'rw', +); + +# hashref where the provision (what a file provides) is the key, +# and an arrayref of the files that provide the feature are the value +has provisions => ( + is => 'ro', + default => quote_sub q{ {} }, +); + +# hashref where the filename is the key, and the value is required provisions in +# an arrayref +has requirements => ( + is => 'ro', + default => quote_sub q{ {} }, +); + +sub file_list_for_provisions { + my ($self, $provisions) = @_; + + if ($self->scan_files && !$self->_scanned_files) { + for my $dir (@{$self->lib_dir}) { + $self->scan_dir($dir); + } + $self->_scanned_files(1); + } + + my %ret; + tie %ret, 'Tie::IxHash'; + for my $requested_provision (@$provisions) { + my $files = $self->files_providing($requested_provision) + + # for now we just use the first file + my $file = $files->[0]; + if (my $requirements = $self->requirements->{$files->[0]}) { + $ret{$_} = 1 for $self->file_list_for_provisions($requirements); + } + $ret{$file} = 1; + } + + return keys %ret; +} + +sub scan_dir { + my ($self, $dir) = @_; + my $dh; + opendir $dh, $dir; + my @files = grep { $_ ne '.' && $_ ne '..' } readdir $dh; + for (@files) { + my $fqfn = "$dir/$_"; + $self->scan_dir($fqfn) if $self->recurse && -d $fqfn; + $self->scan_file($fqfn) if -f $fqfn; + } +} + +sub scan_file { + my ($self, $file) = @_; + open my $fh, '<', $file; + while (<$fh>) { + if (m[//\s*provides:\s*(\S+)]) { + $self->provisions->{$1} ||= []; + push @{$self->provisions->{$1}}, $file + } elsif (m[//\s*requires:\s*(\S+)]) { + $self->requirements->{$file} ||= []; + push @{$self->requirements->{$file}}, $1 + } + } +} + +sub files_providing { + my ($self, $provision) = @_; + + $self->provisions->{$provision} + or die "no such provision '$requested_provision' found!"; +} + +1; + +# Dedicated to Arthur Dale Schmidt +# This code was written at the Tallulalh Travel Center in Louisiana diff --git a/t/basic.t b/t/basic.t new file mode 100644 index 0000000..1970695 --- /dev/null +++ b/t/basic.t @@ -0,0 +1,26 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +use Test::More; + +use Javascript::Dependancy::Manager; + +my $mgr = Javascript::Dependancy::Manager->new( + lib_dir => ['t/js-lib'], + recurse => 1, + provisions => { + extjs => ['t/js-lib/ext/ext-all.js', 't/js-lib/ext/ext-all-debug.js'], + }, + requirements => { + 't/js-lib/ext/ext-all.js' => ['ext-core'], + }, +); + +is_deeply + [$mgr->file_list_for_provisions(['b', 'a'])], + ['t/js-lib/ext/ext-core.js','t/js-lib/ext/ext-all.js','t/js-lib/A.js','t/js-lib/B.js'], + 'basic deps works'; + +done_testing; diff --git a/t/js-lib/A.js b/t/js-lib/A.js new file mode 100644 index 0000000..b0a07ee --- /dev/null +++ b/t/js-lib/A.js @@ -0,0 +1,5 @@ +// provides: a +// requires: extjs +function a(arg) { + console.log(arg); +} diff --git a/t/js-lib/B.js b/t/js-lib/B.js new file mode 100644 index 0000000..ea2911c --- /dev/null +++ b/t/js-lib/B.js @@ -0,0 +1,5 @@ +// provides: b +// requires: a +function b(arg) { + a(arg + 'b') +} diff --git a/t/js-lib/C.js b/t/js-lib/C.js new file mode 100644 index 0000000..83aaf55 --- /dev/null +++ b/t/js-lib/C.js @@ -0,0 +1,5 @@ +// provides: c +// requires: b +function c(arg) { + b(arg + 'c') +} diff --git a/t/js-lib/ext/ext-all-debug.js b/t/js-lib/ext/ext-all-debug.js new file mode 100644 index 0000000..f98fe90 --- /dev/null +++ b/t/js-lib/ext/ext-all-debug.js @@ -0,0 +1,5 @@ +var console = { + log: function(out) { + return out + zomglowlevel(); + } +}; diff --git a/t/js-lib/ext/ext-all.js b/t/js-lib/ext/ext-all.js new file mode 100644 index 0000000..60540f2 --- /dev/null +++ b/t/js-lib/ext/ext-all.js @@ -0,0 +1 @@ +var console = { log: function(out) { return out + zomglowlevel() } }; diff --git a/t/js-lib/ext/ext-core.js b/t/js-lib/ext/ext-core.js new file mode 100644 index 0000000..1487b2b --- /dev/null +++ b/t/js-lib/ext/ext-core.js @@ -0,0 +1,4 @@ +// provides: ext-core +function zomglowlevel() { + return 1 + 2 +}