Package: ican
:wave: icanBecause anything you ask of it, the response isalwaysican.:man_office_worker: MotivationThere are plenty of version bumpers and build tools.  But ican is the only one that is designed for the smallest teams, even the 1 man team.The one man team has different procedures than most.  Often times the one man team forgets to bump version numbers.  Few even bother to keep a code repository besides their own "Dropbox."ican brings big team development practices to small teams.  ican's build number is one feature.  As long as you use ican to automate your docker image builds, deployments, etc. each time your build number is incremented.  That way you always have a different semantic version number, even if you don't purposely bump one of the primary 3 parts.You can even easily use ican to start tagging docker images, as well as git commits.  Soon your small team will be officially "tagging" and "releasing" software like you have a Fortune 500 CI/CD manager.:floppy_disk: InstallInstall the ican package via pypipipinstallican:toolbox: Sample ConfigConfig is done via the .ican file in your project's root diarectory.Sample .ican config file[version]current=0.1.6+build.40previous=0.1.5+build.39[options]log_file=ican.log[file: version]file=./src/__init__.pystyle=semanticvariable=__version__[file: json_example]file=./package.jsonstyle=publicvariable=versionfile_type=json[pipeline: release]step1=./clean_my_project.shstep2=$ICAN(bump {arg_1})step2=git commit -astep3=git tag -a {tag} --signstep4=git push origin master {tag}ExplanationThis config defines the current version as0.1.6with build # 40.All operations will be logged to theican.logfile.ican will update a variable named__version__in./src/__init__.pyany time the bump command is run.ican will use thesemanticstyle of the version when updating this file.A release pipeline has been defined.  More on that later.:exclamation: ImportantTake note, all sections must be unique.  So if you define more than one [file: [LABEL]] section, make sure each one has a unique label.:thumbsdown: :exploding_head:[file: py_code]file=./src/__init__.py...[file: py_code]file=./src/__main__.py:thumbsup: :sunglasses:[file: src_init]file=./src/__init__.py...[file: main]file=./src/__main__.py:triangular_ruler: ConfigSectionKeyValueversioncurrentThis is the value that ican stores the current version number in.versionpreviousThis is the previous version ican uses in case of rollback.optionslog_fileAll operations are logged to disk in this file.  To turn logging off, do not define the log_file.file: [LABEL]fileThe filename of a file ican will update with new versions.  You can use a standard unix glob (*.py) if desired.file: [LABEL]file_typeThe type of file.  Can be "python", "json", or "unknown".  Python/Unknown just search via regex.  Json will use the variable name as a key.  This field is optional as ican will use file extensions to guess the file type.file: [LABEL]styleThe version format to use.  Choices are [semantic, public, pep440, git]file: [LABEL]variableThe variable name pointing to the version string that ican will update when versions are bumped.file: [LABEL]regexUser-supplied python formattted regex string defining how to replace the file's version.pipeline: [LABEL][STEP]A pipeline step is a cli command such asgit commit -a.STEP values MUST to be unique.:mag: User-supplied regexWhen searching for a variable, ican will search for the variable's name, followed by an=symbol, followed by a value in either single or double quotes.  There can be spaces or no spaces on either side of the=symbol.  This covers most use cases.If your use case is more complicated, you can omit thevariableline in your config file and instead include aregexvalue instead.  This should be a pyton formatted regex string with a named group to identify theversionican will replace.[file1]file=./src/__init__.pystyle=semanticregex=__version__\s*=\s*(?P<quote>[\'\"])(?P<version>.+)(?P=quote):computer: PipelinesPipeline IntroPipelines allow you to define cli commands as well as internal ican functions to be run in a batch.  They are defined inside your .ican file.Example:[pipeline: release]step1=$ICAN(bump {arg_1})step2=git add .step3=git commit -m "auto-commit for {tag}"step4=git tag -a {tag} -m "automated tag for release {tag}" --signstep5=git push origin masterstep6=$ICAN(show)You could explicitly tell ican to run thereleasepipeline with the following command:ican run release patchStep1 uses the variablearg_1.{arg_1}references thefirstuser supplied argument.In the example above,patchis the value assigned to {arg_1}ican allows you to leave outrunand simply type:ican release patchFinally, if you do not supply an argument, ican will use the function's default.  The bump default isbuild.  The following command will bump build instead of patch before commiting to git.ican release:exclamation: ImportantEach [pipeline: LABEL] needs a unique LABEL value.  Pipeline steps in the same pipeline must be unique as well.:thumbsdown: :exploding_head:[pipeline: hello]step1=echo 'hello world'...[pipeline: hello]step1=echo 'this is another pipeline'step1=echo 'this example HAS 2 ISSUES'step1=echo 'can you spot them?':thumbsup: :sunglasses:[pipeline: hello]step1=echo 'hello world'...[pipeline: another]step1=echo 'this is another pipeline with a unique label'step2=echo 'this example has unique step names within each pipeline'step3=Batter.home_run()Pipeline ContextThe pipeline context is available in 2 locationsYou can template your pipeline steps, using the {variable_name} format. Example:git push origin master {tag}Before a pipeline runs, ican will inject your shell's environment with all pipeline context variables prefixed with ICAN_.For example you can accesssemanticin your ENV asICAN_SEMANTICPipeline Context VariablesvariableDescriptionsemanticthe current version in semantic formatpublicthe current version in public formatpep440the current version canonical with pep440gitthe current version using git metadatamajorthe major portion of the semantic versionminorthe minor portion of the semantic versionpatchthe patch portion of the semantic versionprereleasethe major portion of the semantic versionbuildthe build numbertagthe git tag,v{public_version}ageREBUILD if bump build, NEW all other bumpsenvDEVELOPMENT or PRODUCTION based on the versionrootthe root directory of your projectpreviousthe previous semantic version:muscle: UseYou can use ican via the CLI in a typical fashion, using the format belowican[command][arguments][options]:dog2: CommandsCommandArgumentsOptionsDescriptionbumpPARTrequiredIncrements thePARTof the semantic version.[major,minor,patch,prerelease]bump--preTOKENIf bumping prerelease, set theTOKENto [alpha,beta,rc,dev]preTOKENrequiredSet the prereleaseTOKENwithout bumping.showSTYLErequiredShows the current version with the formatSTYLE.[semantic,public,pep440,git]runPIPELINErequiredRun the specifiedPIPELINErollbacknoneRollback to the previously persisted version.initnoneInitialize your project with default config in the current directory.:roll_eyes: OptionsThe output and parsing oficancan be controlled with the following options.NameDescription--verboseTo aid in your debugging, verbose prints all messages.--dry-runUseful if used WITH --verbose, will not modify any files.--versionThis will displpay the current version of ican.:eyes: Examples$icaninit

...

$icanshowcurrent0.2.7-beta.3+build.99# Bump with no arguments defaults to bump the build number.$icanbump0.2.7-beta.3+build.100# Now its release time.  Lets bump the minor$icanbumpminor0.3.0+build.101# Oh no, major problem, rollback$icanrollback0.3.0+build.100# Use an aliaw$icandeploy
+BEGINpipeline.NEW.RELEASE
gitcommitsuccessful
+ENDpipeline.NEW.RELEASE1.0.0+build.101# now run our docker pipeline$icanrundocker
+BEGINpipeline.DOCKER
dockercontainerbuild...
+ENDpipeline.DOCKER1.0.0+build.101