diff --git a/CHANGELOG.md b/CHANGELOG.md index 074bfb2..f17f2d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ ### Added - Support for placeholders in flag usage strings +## [2.0.0] +### Added +- `NewStringSlice` and `NewIntSlice` for creating their related types + +### Removed +- the ability to specify `&StringSlice{...string}` or `&IntSlice{...int}`. +To migrate to the new API, you may choose to run [this helper +(python) script](./cli-migrate-slice-types). + ## [1.14.0] - 2016-04-03 (backfilled 2016-04-25) ### Added - Codebeat badge @@ -220,6 +229,7 @@ - Initial implementation. [Unreleased]: https://github.com/codegangsta/cli/compare/v1.14.0...HEAD +[2.0.0]: https://github.com/codegangsta/cli/compare/v1.14.0...v2.0.0 [1.14.0]: https://github.com/codegangsta/cli/compare/v1.13.0...v1.14.0 [1.13.0]: https://github.com/codegangsta/cli/compare/v1.12.0...v1.13.0 [1.12.0]: https://github.com/codegangsta/cli/compare/v1.11.1...v1.12.0 diff --git a/cli-migrate-slice-types b/cli-migrate-slice-types new file mode 100755 index 0000000..5c6cb1f --- /dev/null +++ b/cli-migrate-slice-types @@ -0,0 +1,75 @@ +#!/usr/bin/env python +from __future__ import print_function, unicode_literals + +import argparse +import os +import re +import sys + + +DESCRIPTION = """\ +Migrate arbitrary `.go` sources from the pre-v2.0.0 API for StringSlice and +IntSlice types, optionally writing the changes back to file. +""" +SLICE_TYPE_RE = re.compile( + '&cli\\.(?PIntSlice|StringSlice){(?P[^}]*)}', + flags=re.DOTALL +) + + +def main(sysargs=sys.argv[:]): + parser = argparse.ArgumentParser( + description=DESCRIPTION, + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('basedir', nargs='?', metavar='BASEDIR', + type=os.path.abspath, default=os.getcwd()) + parser.add_argument('-w', '--write', help='write changes back to file', + action='store_true', default=False) + + args = parser.parse_args(sysargs[1:]) + + for filepath in _find_candidate_files(args.basedir): + updated_source = _update_source(filepath) + if args.write: + print('Updating {!r}'.format(filepath)) + + with open(filepath, 'w') as outfile: + outfile.write(updated_source) + else: + print('// -> Updated {!r}'.format(filepath)) + print(updated_source) + + return 0 + + +def _update_source(filepath): + with open(filepath) as infile: + source = infile.read() + return SLICE_TYPE_RE.sub(_slice_type_repl, source) + + +def _slice_type_repl(match): + return 'cli.New{}({})'.format( + match.groupdict()['type'], match.groupdict()['args'] + ) + + +def _find_candidate_files(basedir): + for curdir, dirs, files in os.walk(basedir): + for i, dirname in enumerate(dirs[:]): + if dirname.startswith('.'): + dirs.pop(i) + + for filename in files: + if not filename.endswith('.go'): + continue + + filepath = os.path.join(curdir, filename) + if not os.access(filepath, os.R_OK | os.W_OK): + continue + + yield filepath + + +if __name__ == '__main__': + sys.exit(main())