This repository has been archived by the owner on Aug 23, 2019. It is now read-only.
/
CHANGES
749 lines (457 loc) · 18 KB
/
CHANGES
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
Changelog for yay
=================
3.2.0 (unreleased)
------------------
- The resolver now uses gevent. Dictionary keys are now resolved in parallel.
This means in the face of blocking IO operations, the resolver can continue
to deal with other parts of the graph.
- Simple event listening scheme based on the resolver operation cache. Combine
with the PythonClass to build scripts that react to external events.
- The codebase is now flake8 clean apart from 2 exceptions (defined in
setup.cfg). To run flake8 on yay run ``flake8 yay``.
- The expression parser/lexer are no longer subclasses. This avoids clashes
over lextab.py/parsetab.py.
3.1.1 (2013-11-06)
------------------
- No change release.
3.1.0 (2013-11-06)
------------------
- Now supported on python 3.2 and python 3.3 (in addition to 2.6, 2.7 and
pypy).
- Many fixes to YAML multiline block mode
- Lots of test coverage improvements
- Remove unnecessary support for Extended Slices
- Command line output is prettier
3.0.1 (2013-09-04)
------------------
- Nothing changed yet.
3.0 (2013-09-04)
----------------
- This is a full rewrite on top of the ply parsing framework.
0.0.62 (2012-09-27)
-------------------
- Try importing first as it might yield a hit and save checking the internets
for things.
0.0.61 (2012-09-15)
-------------------
- An earlier version added validation to stop you replacing lists with mappings
or vice versa. However the implementation didn't consider that you might
extend a mapping that comes from a lookup.
0.0.60 (2012-09-15)
-------------------
- Fix filter node. It was previously unaware of its parent when expanded and
this stopped its children from being able to look up values in the global
namespace.
0.0.59 (2012-09-01)
-------------------
- Fix setting GPG_TTY.
0.0.58 (2012-08-15)
-------------------
- Capture GPG failures and throw exceptions. Unfortunately without talking to
GPG over the status fd we can't get much information about what went wrong.
- Run in batch mode. This stops GPG from ignoring the stdout/stderr redirection
but means you now *MUST* use a GPG agent as it can no longer prompt for a
passphrase.
- GPG_TTY is set - this means gpg-agent can actually prompt now.
- Fix ``Config.add`` when using nested dictionaries.
0.0.57 (2012-08-02)
-------------------
- Add new lazy lookup method to the root config object. This is useful if you
are building a lazy iterator over a dictionary key::
def example_iterator(self, expression):
try:
for item in expression.expand():
resolved = item.resolve()
create_obj_from_settings(resolved)
except CreateObjectError:
# You can get line and column from the item object!
except yay.errors.Error:
# Ideal place to wrap Yay errors in your apps exceptions
example_iterator(config.lookup("somekey"))
You can see here that the API lets you defer any messy "key not found"
exceptions until the iterator needs to access they key - and the iterator
already has apropriate exception handling.
- Add additional test cases for backwards compatibility
0.0.56 (2012-07-31)
-------------------
- Code paths are now decorated with tracing context. This ``__context__``
metadata gives a sense of what yay was doing when it went off the handle.
0.0.55 (2012-07-25)
-------------------
- Fix PackageIndex to not warn() on missing package - we capture this
ourselves!
0.0.54 (2012-07-22)
-------------------
- Line number and file information should be available for nodes that have been
cloned leading to much more useful error output.
- Index errors on Sequence nodes will be properly dealt with
- Treating a sequence as a mapping node will trigger an appropriate Yay error.
0.0.53 (2012-07-21)
-------------------
- Allow python code using yay to set default configuration for openers
0.0.52 (2012-07-21)
-------------------
- Fix regression in ``package://`` for existing users..
0.0.51 (2012-07-19)
-------------------
- Introduce a lazily evaluated mechanism for expanding the search path::
.search:
- package://some.egg/
- http://raw.github.com/isotoma/yay/
Any subsequent ``.import`` statements will use the modified search path.
- If a package specified either as part of a .include or as part of a .search
is not available on sys.path then an attempt will be made to install it.
- Can pass config to opener backends using ``.config``. For example, you might
want to have the ``package://`` opener to use your internal package
repository::
.config:
openers:
packages:
index: https://my-python-mirror/simple/
username: joe
password: penguin55
You can use variable subsitution and to define the password in a GPG
encrypted yay file or to push the variable from application that is using
Yay.
- Yay openers support basic auth in the url. If used with .include then use of
secrets to concatenate to hide the password is suggsted::
# Define ${password} in a GPG armored file
.include: home://.credentials.yay.gpg
.search:
- https://username:${password}@svn.yourcompany.org/svn/cookbook/trunk
- ``.include`` and ``.search`` may be a single scalar value rather than a list
if you desire.
0.0.50 (2012-07-10)
-------------------
- Allow expressions to return an empty dictionary::
result: ${site.vhosts else {}}
0.0.49 (2012-06-27)
-------------------
- Added a string replacement function allowing people to do things like::
something: jolly good show
slug: ${replace(something, " ", "-")}
thereafter the value of ``slug`` will be ``jolly-good-show``.
0.0.48 (2012-04-07)
-------------------
- Support in operator during foreach::
result.foreach v in somevalues if v in somelist: ${v}.
0.0.47 (2012-04-06)
-------------------
- Allow expressions to contain literal strings and floats::
result: ${site.description else "No description"}
result2: ${3.212121}
- Allow expressions to return an empty list::
result: ${site.vhosts else []}
- Allow equality checks of undefined keys to pass or fail appropriately without
raising a NoMatching exception::
data:
part1:
a: 1
part2:
c: 2
res1.foreach p in data if data[p].a = 2: ${p}
res2.foreach p in data if data[p].c != 1: ${p}
res1 will be empty as neither part1 nor part2 have an a field with a value of
2, and res2 will contain part1 and part2 as neither have a c field wth a
value of 1.
- Add an ``undefined`` that raises a NoMatch exception when resolved. This
allows one to filter by whether or not a key is present in a mapping.
data:
part1:
a: 1
part2:
c: 2
res.foreach p in data if data[p].c = undefined: ${p}
res will contain part1 as part1 doesn't have a c field.
0.0.46 (2012-04-04)
-------------------
- Fix ``else`` expression inside an ``.include``
0.0.45 (2012-03-22)
-------------------
- You can now pass an etag to the open method of ``Openers``. This will throw a
NotModified exception if etag matching shows the request URI is unchanged.
This can be used to implement caching strategies and reduce the amount of data
that yay pulls over network connections::
>>> from yay.openers import Openers
>>> fp = Openers().open("/tmp/somefile, etag="1234535462356456fa")
NotModified: File '/tmp/somefile' not modified
- All openers will now have an etag property. This property can be None if a
suitable etag cannot be provided. Otherwise it should be some hash that
guarantees the state of the file so that later requests can just ask "has it
changed since it was in this state". To get an etag::
>>> from yay.openers import Openers
>>> fp = Openers().open("/tmp/somefile")
>>> print fp.etag
1234535462356456fa
0.0.44 (2012-03-17)
-------------------
- Fix .select when value that is resolved is a complicated expression.
- Better validation when you accidentally mix up list and mapping types.
0.0.43 (2012-02-12)
-------------------
- Fix handling of paths on searchpath without a scheme.
0.0.42 (2012-01-01)
-------------------
- Change how Django boxing works so that a .bind isn't required for the
boxing mechanism to work. This allows raw Django mdoels to be pushed
into Yay using the ``.add`` API from 0.0.41.
0.0.41 (2011-12-21)
-------------------
- You can inject Python objects into the Yay Config object, as long as Yay
knows how to box them. If you had a Yay file like this::
hello: abc
result: ${hello}
And the following python code::
from yay.config import Config
c = Config()
c.load_uri(example_file)
c.add(dict(hello="xyx"))
Then the following assertion is true::
c.get() == dict(hello="xyz", result="xyz")
0.0.40 (2011-12-13)
-------------------
- Fixes calling macros defined in other files.
0.0.39 (2011-11-30)
-------------------
- Fix string builder so that configs containing secrets can be pickled.
0.0.38 (2011-11-22)
-------------------
- This is a bugfix release to improve existing features, especially boxing of
foreign data.
- Move more code away from direct use of ``Boxed`` to ``BoxingFactory.box``
- Wrap any dictionary objects in a Mapping object so they can be merged with
other mappings that come from within Yay.
0.0.37 (2011-11-20)
-------------------
- Brown paper bag release to remove stray print.
0.0.36 (2011-11-20)
-------------------
- There is now a ``home://`` URL handler. For my laptop this means::
import yay
yay.load_uri("home://foo/bar.yay")
Is equivalent to::
import yay
yay.load_uri("/home/john/foo/bar.yay")
- Improve searchpath handling to better cope with URIs.
- Add support for ``else`` keyword in expressions as per YEP2::
foo:
bar: ${foo.baz else 52}
This is useful for providing sensible defaults in your recipes.
- The loop block is now autoflattening. This means that constructs that yield
lists of lists will be turned into 1-dimensional lists by ``.foreach``. For
example::
somelist:
- - - a
- b
- c
- d
someotherlist.foreach var in somelist: ${var}
The list ``someotherlist`` would now contain::
somelist:
- a
- b
- c
- d
The previous behaviour can be obtained with the ``chain`` modifier::
somelist.foreach var in somelist chain: ${var}
- Add a simple macro language. This is highly EXPERIMENTAL and subject to
frequent syntax tweaks. You can define a reusable block of configuration
using the .define statement. An example of this in Yaybu to create a reusable
virtualenv step::
.define Virtualenv:
- Directory:
name: ${venv.location}
owner: ${venv.owner}
- Execute:
name: create-virtualenv-${venv.location}
command: virtualenv --no-site-packages ${venv.location}
creates: ${venv.location}/bin/pip
- Execute:
name: install-requirements-${venv.location}
command: ${venv.location}/bin/pip install -r ${venv.requirements}
The macro is callable inline as part of an expression. For example::
resources.append:
.foreach venv in virtualenvs: ${Virtualenv!}
Equally you can do this::
.define Virtualenv:
- Directory:
name: ${location}
owner: ${owner}
# SNIP
resources.append:
Virtualenv!:
location: /tmp/example
owner: dave
requirements: /tmp/requirements.txt
0.0.35 (2011-11-12)
-------------------
- This release refactors ProtectedString to make it more useful outside Yay.
Instead of importing ``yay.protectedstring.ProtectedString`` you should
import ``yay.String``
- You can now pass strings to the constructor and they will automatically be
wrapped. Previously you had to pass StringPart's to the constructor. That is
now an internal implementation detail.
- There is now an extend() function. This accepts lists that contains a mixture
of raw strings and other ``String`` objects::
s = String("echo")
y = String("supersekritpassword", secret=True)
s.extend(["a", "b", y, "d"])
- There is now an as_list() function. This returns all the parts you have added
to a string. This is useful if you are building a command line to pass to
subprocess::
s.String(["someprogram", "--pasword"])
s.add_secret("password")
# Log the obfuscated version but execute with the real password
log.info(s.protected)
p = subprocess.Popen(s.as_list(secret=False), cwd="/")
- There is now a ``secret`` call in Yay for exercising secret Yay without
needing to use GPG. This is mainly for test purposes, but might be useful if
you have strings which arent closely guarded secrets yet you dont want them
show in logs. To use it you do something like this::
resources.append:
- Checkout:
name: /checkouts/mycode
repository: http://github.com/whatever
scm_password.secret: mypassword
This example is from Yaybu and would stop Yaybu from logging your SVN
password.
0.0.34 (2011-11-10)
-------------------
- Compose now reuses Opener() rather than creating a new one for each stream
loaded.
0.0.33 (2011-11-10)
-------------------
- You can now pass ``searchpath`` to the ``Config`` object.
0.0.32 (2011-11-10)
-------------------
- Working package:// imports
0.0.31 (2011-11-10)
-------------------
- Better absolute path handling
0.0.30 (2011-11-10)
-------------------
- Any stream objects returned by the ``Openers()`` API now have a ``len`` property.
- The internal ``Openers()`` API can now load from any package on the Python path::
fp = Openers().open("package://some.egg/hello.txt")
0.0.29 (2011-11-10)
-------------------
- The internal ``Openers()`` API now has support for a search path::
fp = Openers(searchpath=['file:///home/john', 'http://google.com']).open("foo.txt")
- The ``Openers()`` API now supports https://
0.0.28 (2011-11-07)
-------------------
- Fully remove all Mapping default crud
0.0.27 (2011-11-03)
-------------------
- Fix ${django.SomeModel} to properly resolve
0.0.26 (2011-11-03)
-------------------
- Add support for a Django DataStore
- Allow objects exposed from Python, including simple method calls
0.0.25 (2011-10-28)
-------------------
- Fix regression in .append
0.0.24 (2011-10-22)
-------------------
- Can now foreach over a mapping
- Add ``.foreach x in y if x.z = a``
- Add '.with expression as foo:'
- Add chain and nochain mode to foreach. chain is the default.
- Major refactoring, context variable is no longer needed to resolve the graph
- The 'semi_resolve' API is now more correctly named 'expand'
0.0.23 (2011-07-26)
-------------------
- $$ escapes $ - so $${foo} is treated as a string, not a variable lookup
0.0.22 (2011-07-19)
-------------------
- Remove spurious debug messages
- Fix .import on a .foreach
0.0.21 (2011-07-19)
-------------------
- New .include directive that can use variables and appear anywhere in file
0.0.20 (2011-06-29)
-------------------
- Change ProtectedString to inherit from basestring
0.0.19 (2011-06-29)
-------------------
- Concept of a protected yay file, where any strings that end up containing
secrets will be obscured
- ProtectedString that handles concatenation of protected and unprocted strings
- GPG used to decrypt .yay.gpg files, any variables they spawn are protected
0.0.18 (2011-06-10)
-------------------
- Brown paper bag to remove stray debugging scaffold
0.0.17 (2011-06-10)
-------------------
- Fix appending to None
- Fix list access where list has already been partially resolved
0.0.16 (2011-06-10)
-------------------
- Add range tests, fixed range() as a ${} expansion
- Added sum() (but no syntax sugar)
- Allow index operations against filters
- Fix iterating over Flatten() nodes
- Fix iterating over ForEach() nodes
- Add test for empty documents that got away
0.0.15 (2011-05-18)
-------------------
- Raise an error if field access is invalid
- Add a LanguageError for displaying helpful messages when yay files
are wrong
- It is now a bug if we raise an error that doesn't descend from
yay.errors.Error
0.0.14 (2011-05-12)
-------------------
- Don't break on empty (e.g. {})
0.0.13 (2011-03-06)
-------------------
- Fix Append nodes
0.0.12 (2011-03-03)
-------------------
- Export that method ;)
0.0.11 (2011-03-03)
-------------------
- Don't be unicode unless needed
- Add a dump() method
0.0.10 (2011-02-22)
-------------------
- Don't chomp whitespace in bracketed_expression
0.0.9 (2011-02-22)
------------------
- Don't chomp whitespace in templated_string
0.0.8 (2011-02-18)
------------------
- Replace 'foreach bar as foo' with 'foreach foo in bar'
0.0.7 (2011-02-16)
------------------
- Numbers starting 0 are treated as base 8.
0.0.6 (2011-02-13)
------------------
- Avoid unicode mapping keys where possible - they break kwargs in Py2.x
0.0.5 (2011-02-09)
------------------
- Add support for nested foreach
- At least for now, support a ruby style .flatten
0.0.4 (2011-02-04)
------------------
- {foo} can be interpreted as a map by YAML. For now, we will use ${foo} to avoid this
- Function calls to python are implemented - there is now range()
- There is now a foo.select key so switch statements can be used
0.0.3 (2011-01-24)
------------------
- Egg packaging fixes
0.0.2 (2011-01-24)
------------------
- Lots more unittests for expression evaluation and expression parsing
- Drop dependency on OrderedDict
0.0.1
-----
- This is still pre-release, no API or language stability guarantees
- Variable resolving is now done in expression tree without a seperate resolve stage
- Uses pyparsing to parse {foo[bar][@.baz > 5]} type syntax
0.0.0
-----
- This is a pre-alpha release to experiment with what we can and can't do.
- New PyYAML Loader subclass for getting ordered maps without ugly !!omap markup
- Resolves {} markup within YAML nodes
- Lazily evaluates .copy, .append and .remove instructions