line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::CpanfileSlipstop::CLI; |
2
|
1
|
|
|
1
|
|
1016
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
3
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
20
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
378
|
use Carton::Snapshot; |
|
1
|
|
|
|
|
139276
|
|
|
1
|
|
|
|
|
30
|
|
6
|
1
|
|
|
1
|
|
579
|
use Getopt::Long qw/:config posix_default no_ignore_case gnu_compat bundling/; |
|
1
|
|
|
|
|
8268
|
|
|
1
|
|
|
|
|
3
|
|
7
|
1
|
|
|
1
|
|
622
|
use Module::CPANfile; |
|
1
|
|
|
|
|
4914
|
|
|
1
|
|
|
|
|
33
|
|
8
|
1
|
|
|
1
|
|
6
|
use Pod::Find qw(pod_where); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
52
|
|
9
|
1
|
|
|
1
|
|
444
|
use Pod::Usage qw(pod2usage); |
|
1
|
|
|
|
|
39709
|
|
|
1
|
|
|
|
|
71
|
|
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
420
|
use App::CpanfileSlipstop::Resolver; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
12
|
1
|
|
|
1
|
|
371
|
use App::CpanfileSlipstop::Writer; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
620
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub new { |
15
|
0
|
|
|
0
|
0
|
|
my ($class) = @_; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# defaults |
18
|
0
|
|
|
|
|
|
bless +{ |
19
|
|
|
|
|
|
|
cpanfile => './cpanfile', |
20
|
|
|
|
|
|
|
snapshot => './cpanfile.snapshot', |
21
|
|
|
|
|
|
|
stopper => 'exact', # or minimum, maximmu |
22
|
|
|
|
|
|
|
dry_run => 0, |
23
|
|
|
|
|
|
|
with_core => 0, |
24
|
|
|
|
|
|
|
silent => 0, |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
remove => 0, |
27
|
|
|
|
|
|
|
help => 0, |
28
|
|
|
|
|
|
|
}, $class; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub run { |
32
|
0
|
|
|
0
|
0
|
|
my ($self, @argv) = @_; |
33
|
|
|
|
|
|
|
|
34
|
0
|
|
|
|
|
|
$self->parse_options(@argv); |
35
|
|
|
|
|
|
|
|
36
|
0
|
0
|
|
|
|
|
return $self->cmd_help if $self->{help}; |
37
|
0
|
0
|
|
|
|
|
return $self->cmd_remove if $self->{remove}; |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
return $self->cmd_feedback; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub parse_options { |
43
|
0
|
|
|
0
|
0
|
|
my ($self, @argv) = @_; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
GetOptions( |
46
|
|
|
|
|
|
|
'cpanfile=s' => \($self->{cpanfile}), |
47
|
|
|
|
|
|
|
'snapshot=s' => \($self->{snapshot}), |
48
|
|
|
|
|
|
|
'stopper=s' => \($self->{stopper}), |
49
|
|
|
|
|
|
|
'dry-run' => \($self->{dry_run}), |
50
|
|
|
|
|
|
|
'with-core' => \($self->{with_core}), |
51
|
|
|
|
|
|
|
'silent' => \($self->{silent}), |
52
|
|
|
|
|
|
|
'remove' => \($self->{remove}), |
53
|
0
|
|
|
|
|
|
'help|h' => \($self->{help}), |
54
|
|
|
|
|
|
|
); |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub cmd_feedback { |
58
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
59
|
|
|
|
|
|
|
|
60
|
0
|
|
|
|
|
|
my $cpanfile = Module::CPANfile->load($self->{cpanfile}); |
61
|
0
|
|
|
|
|
|
my $snapshot = Carton::Snapshot->new(path => $self->{snapshot}); |
62
|
0
|
|
|
|
|
|
$snapshot->load; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
my $resolver = App::CpanfileSlipstop::Resolver->new( |
65
|
|
|
|
|
|
|
cpanfile => $cpanfile, |
66
|
|
|
|
|
|
|
snapshot => $snapshot, |
67
|
|
|
|
|
|
|
with_core => $self->{with_core}, |
68
|
0
|
|
|
|
|
|
); |
69
|
0
|
|
|
|
|
|
$resolver->read_cpanfile_requirements; |
70
|
0
|
|
|
|
|
|
$resolver->merge_snapshot_versions($self->versioning_method, $self->{with_core}); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
my $writer = App::CpanfileSlipstop::Writer->new( |
73
|
|
|
|
|
|
|
cpanfile_path => $self->{cpanfile}, |
74
|
|
|
|
|
|
|
dry_run => $self->{dry_run}, |
75
|
0
|
|
|
|
|
|
); |
76
|
|
|
|
|
|
|
$writer->set_versions( |
77
|
0
|
|
|
0
|
|
|
sub { $resolver->get_version_range($_[0]) }, |
78
|
0
|
0
|
|
0
|
|
|
sub { !$self->{silent} && $self->log(@_) }, |
79
|
0
|
|
|
|
|
|
); |
80
|
|
|
|
|
|
|
|
81
|
0
|
|
|
|
|
|
return 0; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub cmd_remove { |
85
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
|
my $cpanfile = Module::CPANfile->load($self->{cpanfile}); |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my $writer = App::CpanfileSlipstop::Writer->new( |
90
|
|
|
|
|
|
|
cpanfile_path => $self->{cpanfile}, |
91
|
|
|
|
|
|
|
dry_run => $self->{dry_run}, |
92
|
0
|
|
|
|
|
|
); |
93
|
|
|
|
|
|
|
$writer->remove_versions( |
94
|
0
|
0
|
|
0
|
|
|
sub { !$self->{silent} && $self->log(@_) }, |
95
|
0
|
|
|
|
|
|
); |
96
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
return 0; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub cmd_help { |
101
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
pod2usage( |
104
|
|
|
|
|
|
|
-input => pod_where({ -inc => 1 }, 'App::CpanfileSlipstop'), |
105
|
|
|
|
|
|
|
-exitval => 0, |
106
|
|
|
|
|
|
|
); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub versioning_method { |
110
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
return +{ |
113
|
|
|
|
|
|
|
minimum => 'add_minimum', |
114
|
|
|
|
|
|
|
maximum => 'add_maximum', |
115
|
|
|
|
|
|
|
exact => 'exact_version', |
116
|
0
|
|
|
|
|
|
}->{$self->{stopper}}; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub log { |
120
|
0
|
|
|
0
|
0
|
|
my ($self, $log) = @_; |
121
|
|
|
|
|
|
|
|
122
|
0
|
0
|
0
|
|
|
|
return if ($log->{before} || '') eq ($log->{after} || ''); |
|
|
|
0
|
|
|
|
|
123
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
|
my $quote = $log->{quote}; |
125
|
|
|
|
|
|
|
print sprintf "%s: %s -> %s\n", |
126
|
|
|
|
|
|
|
$log->{module}, |
127
|
|
|
|
|
|
|
$log->{before} ? $log->{before} : '(unspecified)', |
128
|
0
|
0
|
|
|
|
|
$log->{after} ? $log->{after} : '(unspecified)'; |
|
|
0
|
|
|
|
|
|
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
1; |