-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathchapter-07.srt
862 lines (669 loc) · 16.3 KB
/
chapter-07.srt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
1
00:00:00,000 --> 00:00:03,977
Chapter 07.
Specifying dependencies.
2
00:00:04,365 --> 00:00:08,580
JC: OK so we just committed the working target class.
3
00:00:09,600 --> 00:00:12,411
It can't do an awful lot just
yet, it can just run the commands.
4
00:00:12,410 --> 00:00:16,251
So if we go back to...
5
00:00:17,817 --> 00:00:21,257
What did we have in here. My test file.
6
00:00:21,250 --> 00:00:28,925
When I was sketching this out earlier,
down here I told each of the targets to build.
7
00:00:28,948 --> 00:00:32,102
They're all just isolated.
8
00:00:32,228 --> 00:00:37,165
A better user interface would be to do that.
9
00:00:37,668 --> 00:00:44,982
And have everything needed to
produce the final result just happen.
10
00:00:46,080 --> 00:00:52,960
For that sort of thing you're going to need to
know for example, that bundle.js will depend on...
11
00:00:54,670 --> 00:00:58,251
hello_js and complimenter_js
12
00:00:58,250 --> 00:01:05,222
Whereas these won't depend on anything.
13
00:01:06,560 --> 00:01:10,700
They are their own things.
14
00:01:10,845 --> 00:01:15,885
Although they do arguably depend on their source code.
15
00:01:19,508 --> 00:01:24,742
In order for the build system to be lazy
and work out if any more work needs doing,
16
00:01:24,754 --> 00:01:27,542
it will need to know about that relationship.
17
00:01:27,540 --> 00:01:32,651
So it's probably advisable if we say...
18
00:01:32,660 --> 00:01:35,702
Here we have these target
objects to represent these things.
19
00:01:35,725 --> 00:01:43,005
but for these source files,
we could say that they are...
20
00:01:44,130 --> 00:01:56,400
For example, hello_coffee is a
Target.new('example/src/hello.coffee',
21
00:01:56,457 --> 00:02:01,634
which actually depends on nothing because the
source code you wrote is not derived from anything.
22
00:02:01,725 --> 00:02:08,011
And it has no build instructions because
you wrote it so it doesn't need generating.
23
00:02:08,902 --> 00:02:13,131
And then this could take that as a dependency.
24
00:02:13,325 --> 00:02:17,920
And you can do the same for
complimenter, and what have you.
25
00:02:19,737 --> 00:02:27,188
I'm on the fence about whether to pass
these things around as values or by name.
26
00:02:27,280 --> 00:02:36,914
Because, to pass this by saying
`example/src/hello.coffee`...
27
00:02:38,830 --> 00:02:45,451
TS: What's the trade off there?
Why would you want to do it one way or the other?
28
00:02:45,542 --> 00:02:51,965
JC: Good question, if you do them by
name you can write your target in any order.
29
00:02:52,434 --> 00:02:58,000
This can be beneficial. This is
supposed to be a declarative system.
30
00:02:58,708 --> 00:03:03,234
It can also mean that you make
dependencies on things that don't exist yet.
31
00:03:03,325 --> 00:03:11,142
So for example complimentor.js
won't exist when you start the build.
32
00:03:11,140 --> 00:03:17,280
The target represents something that will exist
in the future so you don't need the file to exist.
33
00:03:17,340 --> 00:03:25,611
But having the pass by name means that you
can do something for example, by having patterns.
34
00:03:25,645 --> 00:03:30,514
Like if you want to say *.js depends on *.coffee,
35
00:03:30,510 --> 00:03:36,605
we don't want to have to write all these
targets out by hand once the project gets large.
36
00:03:36,651 --> 00:03:42,902
So you may want to have some general
rule for how you get from one to the other.
37
00:03:43,668 --> 00:03:47,840
TS: It sounds like that may
be more complicated though.
38
00:03:49,520 --> 00:03:55,897
JC: Yeah, erh... We can
probably start by passing by value
39
00:03:56,457 --> 00:03:59,554
and if it becomes a problem we can pass by name,
40
00:03:59,550 --> 00:04:04,902
and then have those names be looked up
in something else but turned into the values.
41
00:04:04,925 --> 00:04:08,240
That should be a fairly minor change to make later.
42
00:04:08,308 --> 00:04:12,068
So let's do the pass by value thing.
43
00:04:12,868 --> 00:04:20,217
So if we go back to our spec.
44
00:04:20,240 --> 00:04:24,857
I already had this open
because it was in another shell.
45
00:04:26,868 --> 00:04:33,040
Yes, so... This is all talking
about running instructions.
46
00:04:34,994 --> 00:04:37,142
We also want to talk about having dependencies.
47
00:04:37,165 --> 00:04:44,605
So we've decided that the target is going to
have a new argument, which is its dependencies.
48
00:04:44,754 --> 00:05:02,240
[Silence]
49
00:05:07,005 --> 00:05:11,120
That ought to run but it doesn't... Why not?
50
00:05:11,394 --> 00:05:14,754
[James is thinking]
51
00:05:15,770 --> 00:05:22,617
Oh yes, OK so in the tests we need...
52
00:05:25,154 --> 00:05:31,440
I need to write that properly...
Dependencies is some list.
53
00:05:34,182 --> 00:05:37,200
And I like things that line up.
54
00:05:37,554 --> 00:05:40,491
So that ought to be fine.
55
00:05:43,245 --> 00:05:50,057
So these tests are now testing
a thing that has no dependencies.
56
00:05:52,720 --> 00:06:00,300
Ultimately we would like to have
a target that will depend on something else,
57
00:06:01,302 --> 00:06:06,182
and if you build your target it
will also build the other thing.
58
00:06:09,474 --> 00:06:14,525
Maybe this is where we get
into an integration test scenario.
59
00:06:14,731 --> 00:06:20,365
Because I'm going to have two target objects
maybe writing unit tests against those is...
60
00:06:20,434 --> 00:06:24,982
I could write a test to say when you call
build on this call build on this other thing,
61
00:06:26,091 --> 00:06:29,280
but maybe that's specifying
the implementation too much.
62
00:06:29,794 --> 00:06:35,085
So I'm going to try and write...
63
00:06:38,628 --> 00:06:43,600
spec/features is where I'm
going to put my integration test.
64
00:06:43,668 --> 00:06:50,697
dependent_targets_spec.rb
65
00:06:50,822 --> 00:06:56,330
[Silence]
66
00:06:59,451 --> 00:07:03,074
No that's not how you write specs is it?
67
00:07:03,977 --> 00:07:10,628
describe 'dependent targets' do
68
00:07:11,268 --> 00:07:14,434
[James thinks]
69
00:07:17,428 --> 00:07:26,628
Say when one target depends on another.
70
00:07:29,440 --> 00:07:38,571
As something simple, I'm going to say that if you have...
71
00:07:38,742 --> 00:07:42,731
what's something simple we can
do with files, just like cat-ing them.
72
00:07:42,810 --> 00:07:49,188
So if you have file c that is...
73
00:07:49,840 --> 00:07:53,474
I'll write it in code, that might be a bit clearer.
74
00:07:53,600 --> 00:07:56,194
So if we say...
75
00:07:59,142 --> 00:08:05,165
Not quite sure how to phrase this yet but...
76
00:08:05,188 --> 00:08:08,182
let's say that we have...
77
00:08:08,434 --> 00:08:18,480
There exists a file called a.txt that
just contains an A with a new line in it.
78
00:08:20,160 --> 00:08:30,148
And likewise there are some files called
b and c that have their letters in them.
79
00:08:30,420 --> 00:08:34,822
[Silence]
80
00:08:34,982 --> 00:08:45,325
So if there are those files,
then you have your first target.
81
00:08:47,520 --> 00:08:57,748
And let's put these somewhere... Like in spec/tmp.
82
00:08:57,920 --> 00:09:04,434
[Silence]
83
00:09:04,742 --> 00:09:12,674
So if the first target is spec/tmp/one.txt.
84
00:09:14,994 --> 00:09:21,165
And that's new with that.
85
00:09:21,782 --> 00:09:29,405
And it has no dependencies, or rather
it does have dependencies which are...
86
00:09:32,750 --> 00:09:34,685
Sorry I got a bit side tracked.
87
00:09:34,742 --> 00:09:39,234
So file_a.
88
00:09:39,462 --> 00:09:44,137
TS: So we need targets to represent these files
even though there not going to be built in any way.
89
00:09:47,154 --> 00:09:49,817
There will be some nicer user
interface around this at some point.
90
00:09:49,810 --> 00:09:53,200
But it makes this a bit more
complicated to pass in those values,
91
00:09:53,234 --> 00:09:56,960
because you have to make values
for things that are just primitive files.
92
00:09:56,960 --> 00:09:59,714
TS: Whereas if you identified things by name,
93
00:09:59,710 --> 00:10:04,434
the assumption would have been if I've named
something by name it isn't a target it's just a file.
94
00:10:04,460 --> 00:10:05,748
JC: Yes.
95
00:10:05,780 --> 00:10:17,177
So these have no dependencies in them,
no build instructions, so they can be done like that.
96
00:10:19,508 --> 00:10:21,714
That's b that's c.
97
00:10:21,817 --> 00:10:29,131
So if this depends on file_a and file_b,
98
00:10:29,680 --> 00:10:51,142
And works by cat-ing spec/temp/a.txt
spec/temp/b.txt into spec/temp/one.txt.
99
00:10:55,154 --> 00:11:07,451
And the second target is called second.
100
00:11:09,770 --> 00:11:21,405
And that works by depending
on first_target and file_c.
101
00:11:23,080 --> 00:11:32,640
Then that is going to work by taking one.txt
and c.txt and putting that into the second.
102
00:11:32,731 --> 00:11:38,148
I suppose this could be our before block.
103
00:11:38,370 --> 00:11:50,411
[Silence]
104
00:11:50,651 --> 00:11:52,697
TS: So you haven't actually built anything yet?
105
00:11:52,690 --> 00:11:55,131
JC: No.
106
00:11:59,360 --> 00:12:14,228
If we just build the second target then we expect
File.read(spec/tmp/second.txt) to equal...
107
00:12:16,617 --> 00:12:22,937
A newline, B newline, C newline.
108
00:12:23,177 --> 00:12:27,154
Because everything has
been concatenated together.
109
00:12:27,330 --> 00:12:38,411
[Silence]
110
00:12:38,914 --> 00:12:41,890
I'm going to make some helper functions here.
111
00:12:41,931 --> 00:12:49,531
So I've made this file helper
here, I just need to define that.
112
00:12:51,977 --> 00:12:56,600
I've made this helper because I want everything
to be cleaned up automatically afterwards.
113
00:12:57,268 --> 00:13:01,325
This helper is going to make the file
with that content and keep track of it.
114
00:13:01,320 --> 00:13:05,725
And then use an `after` hook to remove all of them.
115
00:13:05,720 --> 00:13:07,531
TS: OK.
116
00:13:07,588 --> 00:13:15,280
JC: So file utils has a `mkdir_p` function.
117
00:13:18,068 --> 00:13:28,700
We can make that, and then we can `File.open`,
the path name and write content into that.
118
00:13:28,925 --> 00:13:37,634
[Silence]
119
00:13:37,790 --> 00:13:43,108
Then we can store the path name in there.
120
00:13:43,470 --> 00:13:48,045
[Silence]
121
00:13:48,060 --> 00:13:54,102
And then as an `after` hook, we can say...
122
00:13:54,960 --> 00:14:00,148
spec_files.each do path name.
123
00:14:00,845 --> 00:14:05,131
Is it `File.unlink` to delete things?
124
00:14:07,200 --> 00:14:12,354
So then we ought not to be left
with loads of files that exist between tests.
125
00:14:12,365 --> 00:14:17,337
and cause subsequent tests
to not do the right thing.
126
00:14:17,520 --> 00:14:19,485
So does this say what we actually want?
127
00:14:19,520 --> 00:14:22,880
We have 3 files and they have content.
128
00:14:23,108 --> 00:14:28,068
And we've made targets for them and
the first target depends on a and b
129
00:14:28,060 --> 00:14:31,474
and if you cat those two
files together you get one.txt.
130
00:14:31,520 --> 00:14:34,982
The second target depends on
the first target and file c
131
00:14:34,980 --> 00:14:42,308
and if you can cat those two
to make the second file, that works.
132
00:14:42,300 --> 00:14:46,514
The way things are at the moment,
if we just run second_target.build,
133
00:14:47,074 --> 00:14:53,714
it might end up throwing because
this one.txt file won't exist.
134
00:14:54,045 --> 00:15:01,462
So cat in that situation, I can't remember...
If it fails silently and returns zero or not.
135
00:15:01,460 --> 00:15:06,057
We'll find out, but either way.. It should throw
or it shouldn't have the right content in it.
136
00:15:06,114 --> 00:15:08,514
A and B will be missing.
137
00:15:08,742 --> 00:15:14,102
So let's have a go at running those spec features.
138
00:15:15,702 --> 00:15:20,365
No variable `second_target` on where... 38.
139
00:15:22,982 --> 00:15:25,131
Ah yes.
140
00:15:25,360 --> 00:15:31,222
[Silence]
141
00:15:31,420 --> 00:15:36,148
That's a local variable that split apart.
142
00:15:36,445 --> 00:15:37,828
Just run that.
143
00:15:37,930 --> 00:15:43,771
We've got a failed command from line
38 where we tried to build that thing.
144
00:15:44,091 --> 00:15:48,148
I assume because cat is failing.
145
00:15:49,657 --> 00:15:56,034
It would be nice if that error told us what
command had failed. That would be really helpful.
146
00:15:56,057 --> 00:16:01,154
So let's make it do that, so
we know, lib/fakemake/target.
147
00:16:03,428 --> 00:16:07,257
Raise fake command.
148
00:16:11,410 --> 00:16:23,371
Unless system(instruction)
message equals "command failed" with the instruction.
149
00:16:23,554 --> 00:16:25,188
TS: Right.
150
00:16:25,490 --> 00:16:32,194
[Silence]
151
00:16:32,342 --> 00:16:34,125
JC: Raise that.
152
00:16:34,400 --> 00:16:38,788
[Silence]
153
00:16:38,880 --> 00:16:45,090
Command failed: cat spec/tmp/one. So that is expected.
154
00:16:48,205 --> 00:16:50,685
I hope those files are not hanging around in tmp.
155
00:16:50,680 --> 00:17:00,228
So this knows how to clean up the files we created
with `file` but it doesn't know how to clean up.
156
00:17:02,320 --> 00:17:04,137
TS: How you going to fix that?
157
00:17:04,420 --> 00:17:07,074
JC: We could poke those things into
the array so it knows about them,
158
00:17:07,085 --> 00:17:09,508
but it still feels a little unclean.
159
00:17:09,542 --> 00:17:11,542
I accidentally made a new shell there.
160
00:17:15,577 --> 00:17:17,965
We could just nuke the tmp directory.
161
00:17:17,960 --> 00:17:23,462
I think that's maybe why I put them in a directory in
the first place, so you can just wipe the slate clean.
162
00:17:23,460 --> 00:17:29,417
So let's do that and then we
don't need this tracking stuff.
163
00:17:32,022 --> 00:17:37,417
I have put this `spec/tmp` all over the test,
maybe that's something I should clean up.
164
00:17:37,428 --> 00:17:39,485
I maybe wanted to say...
165
00:17:39,691 --> 00:17:46,240
What I originally wanted to do was say file
a.text and then have that created spec/tmp.
166
00:17:46,270 --> 00:17:52,891
But to make these commands work I would
have had to change process directory into there.
167
00:17:52,910 --> 00:17:56,217
Which we could do, I think I'm happier with that.
168
00:17:56,240 --> 00:18:03,988
Lets remove those.
169
00:18:04,190 --> 00:18:08,994
[Silence]
170
00:18:09,142 --> 00:18:14,530
Because they're really just
crufting everything up.
171
00:18:14,605 --> 00:18:21,588
If we do that... `in_tmp_dir`.
172
00:18:21,860 --> 00:18:30,171
[Silence]
173
00:18:30,400 --> 00:18:38,022
FileUtils has another nice helper function
where you can FileUtils.cd to somewhere.
174
00:18:38,160 --> 00:18:42,091
[Silence]
175
00:18:42,308 --> 00:18:44,800
Just pass the block through, (it takes a block).
176
00:18:44,890 --> 00:18:48,548
It changes working directory
into somewhere, runs the block,
177
00:18:48,560 --> 00:18:53,474
and then comes back out again to
wherever you were before, which is kind of nice.
178
00:18:53,714 --> 00:18:56,868
TS: So you're not having to do
any clean up of the current stuff,
179
00:18:56,868 --> 00:18:58,860
it just goes back to what it was when you started.
180
00:18:58,860 --> 00:19:03,062
JC: Exactly.
181
00:19:03,900 --> 00:19:06,982
So creating those files...
182
00:19:07,531 --> 00:19:13,200
We don't do anything, these just make target objects,
they don't run system calls or write any files.
183
00:19:13,310 --> 00:19:23,005
So file would have to make that temp directory.
184
00:19:23,520 --> 00:19:27,017
And then put that in here.
185
00:19:27,280 --> 00:19:33,542
So if we make those files inside spec/tmp
and then run everything in that directory,
186
00:19:33,657 --> 00:19:47,120
and afterwards remove it again,
everything should be OK, I think.
187
00:19:48,411 --> 00:19:51,040
Let's see what it makes of that.
188
00:19:52,280 --> 00:19:57,988
"Wrong number of arguments (0 for 1) on line 10"
189
00:20:01,850 --> 00:20:06,022
Oh I didn't actually pass an argument
to that one when I used it did I?
190
00:20:06,914 --> 00:20:11,062
It's just to to hide where
we're storing things from the code.
191
00:20:14,640 --> 00:20:19,188
Command failed cat one with c didn't work
192
00:20:20,102 --> 00:20:24,400
And that temp directory has gone away, so that's nice.
193
00:20:24,880 --> 00:20:27,314
OK, I feel better about that.
TS: OK good.