File Coverage

blib/lib/Standup/Diary.pm
Criterion Covered Total %
statement 37 41 90.2
branch 2 8 25.0
condition n/a
subroutine 12 14 85.7
pod 5 7 71.4
total 56 70 80.0


line stmt bran cond sub pod time code
1             package Standup::Diary;
2              
3 2     2   308792 use v5.28;
  2         16  
4              
5 2     2   1556 use Config::Tiny;
  2         3645  
  2         89  
6 2     2   1793 use Object::Pad ':experimental';
  2         30310  
  2         11  
7 2     2   4032 use Path::Tiny;
  2         64956  
  2         412  
8              
9 2     2   1681 use Standup::Role::Project;
  2         9  
  2         157  
10 2     2   3282 use Standup::Role::Date;
  2         6  
  2         119  
11 2     2   1175 use Standup::Diary::Template;
  2         12  
  2         869  
12              
13             our $VERSION = '0.07_03';
14             $VERSION =~ tr/_//d;
15              
16             class Standup::Diary :does( Date ) :does( Project ) {
17              
18 0 0   0 1 0 field $config :accessor :param { Config::Tiny->read('diary.conf') };
  0         0  
19              
20 1 50   1 1 151 field $daily_data_path :accessor;
  1         12  
21              
22 2     2 1 3843 field $data_dir :param :reader;
  2         19  
23              
24 2 0   2 0 6 field $template :writer :accessor;
  2     0 1 6  
  0         0  
  0         0  
25              
26 3     3 1 6 method init_daily_data_path ($path) {
  3         9  
  3         25  
  3         7  
27             $daily_data_path = $data_dir ?
28             path( $data_dir . '/' . $path ) :
29 3 50       25 path( $config->{data}->{path} . '/' . $path );
30             }
31              
32             method write {
33              
34             $self->set_template( Standup::Diary::Template->new(
35             date => $self->date,
36             project_name => $self->project_name
37             ));
38              
39             if ( $self->should_create_dir ) {
40             say "$daily_data_path should be created";
41             $self->create_directories_tree;
42             } else {
43             $self->init_daily_data_path($self->build_path($self->date->ymd('/')));
44             }
45              
46             my $file_path = path($self->build_full_file_path);
47              
48             path($file_path)->spew_utf8($template->render) and say "Diary entry created $file_path"
49             unless $file_path->exists and say "Entry already exist";
50              
51             }
52              
53             # TODO should have a Standup::Diary::Path object for those
54             method build_full_file_path {
55             return $daily_data_path .
56             '/' .
57             $self->date->ymd .
58             '_' .
59             lc $self->project_name .
60             '.md';
61             }
62              
63 3     3 0 159 method build_path ($date) {
  3         10  
  3         6  
  3         5  
64 3         25 my ($path) = $date =~ m/ \d{4} \/ \d{2} /gx ;
65 3         17 return $path;
66             }
67              
68             method should_create_dir {
69             $self->init_daily_data_path($self->build_path($self->date->ymd('/')));
70             return $daily_data_path->exists ? 0 : 1;
71             }
72              
73             method create_directories_tree {
74              
75             # Unimplemented, see #29
76             if ($self->date->day_of_month == 1 ) {
77             # TODO if first day of the month
78             # Create a Priorities file
79             }
80              
81             my @created = $daily_data_path->mkpath;
82             say "Created $daily_data_path" if @created;
83             }
84             }
85              
86             =encoding utf8
87              
88             =head1 NAME
89              
90             Standup::Diary - Manage a simple Markdown journal for your daily standups
91              
92             =head1 SYNOPSIS
93              
94             # From command line
95             diary --data-dir /home/smonff/diary/ --project-name SeriousWork
96              
97             # Programmatic usage
98             my $diary = Standup::Diary->new( data_dir => $data_dir, project_name => $project_name );
99              
100             $diary->write();
101              
102              
103             =head1 DESCRIPTION
104              
105             This module is the implementation of the L command, that can help to keep
106             a directory of organized daily notes aimed at standup preparation and
107             presentation.
108              
109             It provides a couple of ways to customize the notes template.
110              
111             It use internal tools built with CPAN modules:
112              
113             =over 2
114              
115             =item Standup::Diary::Template
116              
117             The Markdown template where your data are interpolated.
118              
119             =item Standup::Role::Date
120              
121             Provide date features for all the C uses.
122              
123             =item Standup::Role::Project
124              
125             Provide a project name, so far.
126              
127             =back
128              
129             =head1 MOTIVATIONS
130              
131             Daily standups are a common, tried and tested modern work methodology. They are
132             I<"brief, daily collaboration meeting in which the team review progress from the
133             previous day, declares intentions for the current day, and highlights any
134             obstacles encountered or anticipated"> (L
135             meeting in which the team review progress from the previous day, declares
136             intentions for the current day, and highlights any obstacles encountered or
137             anticipated.>).
138              
139             This tool is supposed to provide self-support for persons:
140              
141             =over 2
142              
143             =item Who struggle with daily standups presentations oral expression
144              
145             =item Surely familiar with the Perl ecosystem
146              
147             =back
148              
149             =head2 How did it start?
150              
151             Social anxiety can make my standup presentation very confusing. I also tend to
152             forget key points if improvising, due to the stress of having no talk notes
153             support. Keeping a diary of my thoughts drastically helped me to stay calm and
154             collaborate better with the various teams I worked with. And if they are well
155             sorted by year, month and day, it makes very easy to find old notes for eventual
156             later usage.
157              
158             =head2 Ready for production
159              
160             I have been using it at work since 2021 and it helped me to reduce the stress of
161             standups and meeting.
162              
163             =head2 Methodology
164              
165             Every morning, create the daily file by running C. It's template is a
166             simple 3 items list. Open the day file in C<$data_dir/$year/$month/> and stash
167             your thoughts by using the following methodology:
168              
169             =over 2
170              
171             =item C
172              
173             List of tasks you accomplished in the previous day
174              
175             =item C
176              
177             List of tasks you plan to accomplish today
178              
179             =item C
180              
181             List of eventual blockers, so that your colleagues can support you
182              
183             =back
184              
185             Then just read the notes during the daily standup.
186              
187             =head2 Experiment with Object::Pad
188              
189             L is my pet project for Perl's Corinna implementation of the
190             core OOP features. C use L, not the C feature
191             introduced in Perl C<5.40>. L is the test bed for the new core OO
192             system.
193              
194             =head1 INSTALLATION
195              
196             =head2 For common usage
197              
198             cpanm Standup::Diary
199              
200             It will make the C command available in the C<~/perl5/bin/> directory.
201             Should be available in your C.
202              
203             See L for command line usage.
204              
205             =head2 For development
206              
207             # Install a Perl module manager
208             apt install carton
209              
210             git clone git@codeberg.org:smonff/Diary.git
211              
212             cd Diary
213              
214             # Install CPAN dependencies
215             carton install
216              
217             =head1 How to use it?
218              
219             I set an alias in my C<.bashrc>. Should also work in your own-favorite-shell:
220              
221             alias diary="diary --data-dir /home/smonff/diary --project-name SeriousWork";
222              
223             Each morning, before my work standup, I run C. It create a Markdown file
224             in the specified C<--project-name> directory. I then edit my thoughts with an
225             editor.
226              
227             See L for command line usage.
228              
229             =head1 FIELDS
230              
231             =head2 config
232              
233             =head2 daily_data_path
234              
235             =head2 data_dir
236              
237             =head2 template
238              
239             A L object.
240              
241             =head1 METHODS
242              
243             =head2 build_full_file_path()
244              
245             =head2 build_path($self->date->ymd('/'))
246              
247             Use the date from C to build the final path file name.
248              
249             =head2 create_directories_tree()
250              
251             If C<$self->should_create_dir()> returns a true value, it would take care of the
252             directory creation using L C.
253              
254             =head2 init_daily_data_path($file_path)
255              
256             Helper that initialize C<$daily_data_path> with a C instance
257             for the current day diary entry.
258              
259             # foo/2022/03 (Path::Tiny)
260             $self->init_daily_data_path($self->build_path)
261              
262             =head2 should_create_dir()
263              
264             Check if a new I or I directory should be created so that we can
265             store the standup file. In simplier words: are we the first day of the year, or
266             of the month?
267              
268             =head2 write()
269              
270             This is C entry point, AKA C.
271              
272             =head1 TODOs
273              
274             =over 2
275              
276             =item Make the template configurable by setting it in a separate file
277              
278             =item Retrieve TODOS from previous days
279              
280             =back
281              
282             See the L.
283              
284             =head1 SEE ALSO
285              
286             A couple of similar tools:
287              
288             =over 2
289              
290             =item L
291              
292             On the CPAN, this is pretty much all what I found. I like the spirit of this
293             one.
294              
295             =item L
296              
297             A similar effort written in Bash.
298              
299             =back
300              
301             =head1 ACKNOWLEDGEMENTS
302              
303             Thanks to the maintainers of L, L, L,
304             L, L.
305              
306             =head1 LICENSE
307              
308             Copyright 2022-2024 Sebastien Feugère
309              
310             This library is free software; you can redistribute it and/or modify it under
311             the Artistic License 2.0.
312              
313             See L.
314              
315             =head1 AUTHOR
316              
317             Sébastien Feugère - seb@feugere.net
318              
319             =cut