├── .fish.rc
├── .gitattributes
├── .github
└── workflows
│ ├── pre-commit.yml
│ └── test.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .rc
├── Changes
├── Intro.pod
├── License
├── Makefile
├── Meta
├── ReadMe.pod
├── doc
├── comparison.swim
├── git-subrepo.swim
└── intro-to-subrepo.swim
├── ext
├── bashplus
│ ├── .gitrepo
│ ├── .travis.yml
│ ├── Changes
│ ├── License
│ ├── Makefile
│ ├── Meta
│ ├── ReadMe.pod
│ ├── bin
│ │ └── bash+
│ ├── doc
│ │ └── bash+.swim
│ ├── lib
│ │ └── bash+.bash
│ ├── man
│ │ ├── man1
│ │ │ └── bash+.1
│ │ └── man3
│ │ │ └── bash+.3
│ └── test
│ │ ├── base.t
│ │ ├── die.t
│ │ ├── fcopy.t
│ │ ├── lib
│ │ └── foo
│ │ │ ├── bar.bash
│ │ │ └── foo.bash
│ │ ├── setup
│ │ ├── shellcheck.t
│ │ ├── source-bash+-std.t
│ │ ├── source-bash+.t
│ │ ├── use.t
│ │ └── version-check.t
└── test-more-bash
│ ├── .gitrepo
│ ├── .travis.yml
│ ├── Changes
│ ├── License
│ ├── Makefile
│ ├── Meta
│ ├── ReadMe.pod
│ ├── doc
│ └── test-more.swim
│ ├── ext
│ ├── bashplus
│ │ ├── .gitrepo
│ │ ├── .travis.yml
│ │ ├── Changes
│ │ ├── License
│ │ ├── Makefile
│ │ ├── Meta
│ │ ├── ReadMe.pod
│ │ ├── bin
│ │ │ └── bash+
│ │ ├── doc
│ │ │ └── bash+.swim
│ │ ├── lib
│ │ │ └── bash+.bash
│ │ ├── man
│ │ │ ├── man1
│ │ │ │ └── bash+.1
│ │ │ └── man3
│ │ │ │ └── bash+.3
│ │ └── test
│ │ │ ├── base.t
│ │ │ ├── die.t
│ │ │ ├── fcopy.t
│ │ │ ├── lib
│ │ │ └── foo
│ │ │ │ ├── bar.bash
│ │ │ │ └── foo.bash
│ │ │ ├── setup
│ │ │ ├── shellcheck.t
│ │ │ ├── source-bash+-std.t
│ │ │ ├── source-bash+.t
│ │ │ └── use.t
│ └── test-tap-bash
│ │ ├── .gitrepo
│ │ ├── .travis.yml
│ │ ├── Changes
│ │ ├── License
│ │ ├── Makefile
│ │ ├── Meta
│ │ ├── ReadMe.pod
│ │ ├── doc
│ │ └── test-tap.swim
│ │ ├── lib
│ │ └── test
│ │ │ └── tap.bash
│ │ ├── man
│ │ └── man3
│ │ │ └── test-tap.3
│ │ └── test
│ │ ├── bail_out.t
│ │ ├── done.t
│ │ ├── fail.t
│ │ ├── fail_fast.t
│ │ ├── helper.bash
│ │ ├── pass.t
│ │ ├── plan.t
│ │ ├── shellcheck.t
│ │ ├── skip_all.t
│ │ ├── tap.t
│ │ └── test
│ │ ├── bail.t
│ │ ├── fail.t
│ │ ├── fail_fast.t
│ │ ├── skip-all-init.t
│ │ └── skip-all-plan.t
│ ├── lib
│ └── test
│ │ └── more.bash
│ ├── man
│ └── man3
│ │ └── test-more.3
│ └── test
│ ├── fail.t
│ ├── more.t
│ ├── pass.t
│ ├── setup
│ ├── shellcheck.t
│ ├── skip_all.t
│ └── test
│ ├── fail1.t
│ └── skip_all.t
├── lib
├── git-subrepo
└── git-subrepo.d
│ ├── bash+.bash
│ └── help-functions.bash
├── man
└── man1
│ └── git-subrepo.1
├── note
├── 0.4.0
├── AllGitCmds
├── Cases
├── Commands
├── Dags
├── Gists
├── Links
├── Plugins
├── Spec
├── Story1
├── ToDo
├── design.swim
├── design2.swim
├── pull-dance.txt
├── recreate-rebase-conflict.sh
├── subtree-rebase-fail-example
│ └── test.bash
├── test-subrepo-push.sh
└── test.sh
├── pkg
└── bin
│ ├── generate-completion.pl
│ └── generate-help-functions.pl
├── share
├── completion.bash
├── enable-completion.sh
├── git-completion.bash
├── git-subrepo.fish
└── zsh-completion
│ └── _git-subrepo
└── test
├── Dockerfile
├── branch-all.t
├── branch-rev-list-one-path.t
├── branch-rev-list.t
├── branch.t
├── clean.t
├── clone-annotated-tag.t
├── clone.t
├── compile.t
├── config.t
├── encode.t
├── error.t
├── fetch.t
├── gitignore.t
├── init.t
├── issue29.t
├── issue95.t
├── issue96.t
├── pull-all.t
├── pull-merge.t
├── pull-message.t
├── pull-new-branch.t
├── pull-ours.t
├── pull-theirs.t
├── pull-twice.t
├── pull-worktree.t
├── pull.t
├── push-after-init.t
├── push-after-push-no-changes.t
├── push-force.t
├── push-new-branch.t
├── push-no-changes.t
├── push-squash.t
├── push.t
├── rebase.t
├── reclone.t
├── repo
├── bar
│ ├── HEAD
│ ├── config
│ ├── objects
│ │ ├── 87
│ │ │ └── 46903fdb1b9c2101377880125917c2e05b4d69
│ │ ├── 94
│ │ │ └── c86ffc745232d89f78c6f895e11e71272518db
│ │ ├── 1f
│ │ │ └── 0c4b264caed0126814a0ede851a1e0b4e16ae6
│ │ ├── c6
│ │ │ └── 76c57b6576743fa56278527aa60ebd2e202a7c
│ │ ├── e6
│ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ │ └── f6
│ │ │ └── 2a8ff3feadf39b0a98f1a86ec6d1eb33858ee9
│ └── refs
│ │ ├── heads
│ │ └── master
│ │ └── tags
│ │ └── A
├── foo
│ ├── HEAD
│ ├── config
│ ├── objects
│ │ ├── a0
│ │ │ └── f4cdaaf533a936296cdebbed8206c3b9ededa8
│ │ ├── e2
│ │ │ └── 1291a1ad392a9d4c51dd9586804f1467b28afd
│ │ └── e6
│ │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ └── refs
│ │ └── heads
│ │ └── master
└── init
│ ├── HEAD
│ ├── config
│ ├── objects
│ ├── 11
│ │ └── 523f5dcf03b4c89b592dc8a3d0308f68da2386
│ ├── 14
│ │ └── 2addf8ec5f37334e837440122c62f2c68a29ad
│ ├── 32
│ │ └── 5180321750a21cd7a4e7ecda319e557a4f6a09
│ ├── 58
│ │ └── 931fc1bd559b59c41ea738fc7ad04f9ad01bd3
│ ├── 75
│ │ └── fa6584e748f57eff06eebdc55e9ac21d4fcbf2
│ ├── 80
│ │ └── 2d5edbd5e1cb7fca82b5bd38e7c8a0a496fb20
│ ├── 94
│ │ └── 7b3d714c38791e95ad6f928b48c98bb8708acd
│ ├── 95
│ │ └── e1f2df3f4d5f3d7a60588c25a7ca8a913d3c2a
│ ├── 3d
│ │ └── 918c6901c02f43af5d31779dd5e1f9166aeb36
│ ├── 3e
│ │ └── 4cb596066dce63ba4d047abddb677389b65e19
│ ├── 4b
│ │ └── 6e53022e7a04f07887697e4f3d7c377fd9822b
│ ├── 5e
│ │ └── c0c28e1b806f25efdca18fcf7a74b49c3755bd
│ ├── b1
│ │ └── 5f4a7666baf40d949548ead946a3370e273479
│ ├── c3
│ │ └── ee8978c4c5d84c3b7d00ba8e5906933d027882
│ ├── c8
│ │ └── b0bffbc405ef3fad7354ff833fbec36d67ddfa
│ ├── dd
│ │ └── 8bdb934ec848137f011fe423b185505c343626
│ ├── e2
│ │ └── 9be58c767cfeb27235c995d293a7d71aac0135
│ ├── ee
│ │ └── 1224401fc6aac595145fa727dcf6706ac8aec1
│ └── f1
│ │ └── cc1a657b2e805c400f5dcaaa76bd29c6178b1b
│ └── refs
│ └── heads
│ └── master
├── setup
├── status.t
├── submodule.t
└── zsh.t
/.fish.rc:
--------------------------------------------------------------------------------
1 | #------------------------------------------------------------------------------
2 | #
3 | # This is the `git-subrepo` initialization script.
4 | #
5 | # This script turns on the `git-subrepo` Git subcommand and its manpages, for
6 | # the *Fish* shell.
7 | #
8 | # Just add a line like this to your `~/.config/fish/config.fish`:
9 | #
10 | # source /path/to/git-subrepo/.fish.rc
11 | #
12 | #------------------------------------------------------------------------------
13 |
14 | set GIT_SUBREPO_ROOT (dirname (realpath (status --current-filename)))
15 | set PATH $GIT_SUBREPO_ROOT/lib $PATH
16 |
17 | set -q MANPATH || set MANPATH ''
18 | set MANPATH $MANPATH $GIT_SUBREPO_ROOT/man
19 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 |
--------------------------------------------------------------------------------
/.github/workflows/pre-commit.yml:
--------------------------------------------------------------------------------
1 | name: pre-commit
2 |
3 | on:
4 | pull_request:
5 | push:
6 |
7 | jobs:
8 | pre-commit:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - uses: actions/setup-python@v3
13 | - uses: pre-commit/action@v3.0.1
14 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches: [ '*' ]
6 | pull_request:
7 | branches: [ '*' ]
8 |
9 | jobs:
10 | test:
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | matrix:
14 | os: [ubuntu-latest, macos-latest]
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - if: startsWith(matrix.os, 'macos')
19 | run: brew install bash
20 | - run:
21 | git config --global user.email "you@example.com";
22 | git config --global user.name "Your Name";
23 | git config --global init.defaultBranch "master";
24 | git config --global --add safe.directory "$PWD";
25 | git config --global --add safe.directory "$PWD.git";
26 | - if: startsWith(matrix.os, 'macos')
27 | run: make test
28 | - if: startsWith(matrix.os, 'ubuntu')
29 | run: make docker-tests
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /test/tmp/
2 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v5.0.0
4 | hooks:
5 | - id: check-yaml
6 | - id: end-of-file-fixer
7 | - id: check-illegal-windows-names
8 | - id: check-merge-conflict
9 | - id: trailing-whitespace
10 | - id: check-executables-have-shebangs
11 | - id: check-shebang-scripts-are-executable
12 | exclude: \.t$
13 | - repo: https://github.com/koalaman/shellcheck-precommit
14 | rev: v0.10.0
15 | hooks:
16 | - id: shellcheck
17 | args: [-x]
18 | exclude: |
19 | (?x)^(ext/.*|
20 | share/git-completion.bash
21 | )$
22 |
--------------------------------------------------------------------------------
/.rc:
--------------------------------------------------------------------------------
1 | # shellcheck shell=bash disable=2128
2 |
3 | #------------------------------------------------------------------------------
4 | #
5 | # This is the `git-subrepo` initialization script.
6 | #
7 | # This script turns on the `git-subrepo` Git subcommand, its manpages and TAB
8 | # completion for the *Bash* and *zsh* shells.
9 | #
10 | # Just add a line like this to your shell startup configuration:
11 | #
12 | # source /path/to/git-subrepo/.rc
13 | #
14 | #------------------------------------------------------------------------------
15 |
16 | [[ -n ${ZSH_VERSION-} ]] &&
17 | GIT_SUBREPO_ROOT=$0 ||
18 | GIT_SUBREPO_ROOT=$BASH_SOURCE
19 |
20 | [[ $GIT_SUBREPO_ROOT =~ ^/ ]] ||
21 | GIT_SUBREPO_ROOT=$PWD/$GIT_SUBREPO_ROOT
22 |
23 | GIT_SUBREPO_ROOT=$(
24 | cd "$(dirname "$GIT_SUBREPO_ROOT")" || return
25 | pwd
26 | ) || return
27 | export GIT_SUBREPO_ROOT
28 |
29 | export PATH=$GIT_SUBREPO_ROOT/lib:$PATH
30 | export MANPATH=$GIT_SUBREPO_ROOT/man:$MANPATH
31 |
32 | source "$GIT_SUBREPO_ROOT/share/enable-completion.sh"
33 |
--------------------------------------------------------------------------------
/License:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2020 Ingy döt Net
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SHELL := bash
2 |
3 | # Make sure we have git:
4 | ifeq ($(shell which git),)
5 | $(error 'git' is not installed on this system)
6 | endif
7 |
8 | # Set variables:
9 | NAME := git-subrepo
10 | LIB := lib/$(NAME)
11 | DOC := doc/$(NAME).swim
12 | MAN1 := man/man1
13 | EXT := $(LIB).d
14 | EXTS := $(shell find $(EXT) -type f) \
15 | $(shell find $(EXT) -type l)
16 | SHARE = share
17 |
18 | # Install variables:
19 | PREFIX ?= /usr/local
20 | INSTALL_LIB ?= $(DESTDIR)$(shell git --exec-path)
21 | INSTALL_EXT ?= $(INSTALL_LIB)/$(NAME).d
22 | INSTALL_MAN1 ?= $(DESTDIR)$(PREFIX)/share/man/man1
23 |
24 | # Docker variables:
25 | DOCKER_TAG ?= 0.0.7
26 | DOCKER_IMAGE := ingy/bash-testing:$(DOCKER_TAG)
27 | BASH_VERSIONS ?= 5.2 5.1 5.0 4.4 4.3 4.2 4.1 4.0
28 | DOCKER_TESTS := $(BASH_VERSIONS:%=docker-test-%)
29 | GIT_VERSIONS := 2.48 2.40 2.30 2.29 2.25 2.17 2.7
30 |
31 | prove ?=
32 | test ?= test/
33 | bash ?= 5.2
34 | git ?= 2.48
35 |
36 | # Basic targets:
37 | default: help
38 |
39 | help:
40 | @echo 'Makefile rules:'
41 | @echo ''
42 | @echo 'test Run all tests'
43 | @echo 'install Install $(NAME)'
44 | @echo 'uninstall Uninstall $(NAME)'
45 | @echo 'env Show environment variables to set'
46 |
47 | .PHONY: test
48 | test:
49 | prove $(prove) $(test)
50 |
51 | test-all: test docker-tests
52 |
53 | docker-test:
54 | $(call docker-make-test,$(bash),$(git))
55 |
56 | docker-tests: $(DOCKER_TESTS)
57 |
58 | $(DOCKER_TESTS):
59 | $(call docker-make-test,$(@:docker-test-%=%),$(git))
60 |
61 | # Install support:
62 | install:
63 | install -d -m 0755 $(INSTALL_LIB)/
64 | install -C -m 0755 $(LIB) $(INSTALL_LIB)/
65 | install -d -m 0755 $(INSTALL_EXT)/
66 | install -C -m 0644 $(EXTS) $(INSTALL_EXT)/
67 | install -d -m 0755 $(INSTALL_MAN1)/
68 | install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
69 |
70 | # Uninstall support:
71 | uninstall:
72 | rm -f $(INSTALL_LIB)/$(NAME)
73 | rm -fr $(INSTALL_EXT)
74 | rm -f $(INSTALL_MAN1)/$(NAME).1
75 |
76 | env:
77 | @echo "export PATH=\"$$PWD/lib:\$$PATH\""
78 | @echo "export MANPATH=\"$$PWD/man:\$$MANPATH\""
79 |
80 | # Doc rules:
81 | .PHONY: doc
82 | update: doc compgen
83 |
84 | force:
85 |
86 | doc: ReadMe.pod Intro.pod $(MAN1)/$(NAME).1
87 | perl pkg/bin/generate-help-functions.pl $(DOC) > \
88 | $(EXT)/help-functions.bash
89 |
90 | ReadMe.pod: $(DOC) force
91 | swim --to=pod --wrap --complete $< > $@
92 |
93 | Intro.pod: doc/intro-to-subrepo.swim force
94 | swim --to=pod --wrap --complete $< > $@
95 |
96 | $(MAN1)/%.1: doc/%.swim Makefile force
97 | swim --to=man --wrap $< > $@
98 |
99 | compgen: force
100 | perl pkg/bin/generate-completion.pl bash $(DOC) $(LIB) > \
101 | $(SHARE)/completion.bash
102 | perl pkg/bin/generate-completion.pl zsh $(DOC) $(LIB) > \
103 | $(SHARE)/zsh-completion/_git-subrepo
104 | perl pkg/bin/generate-completion.pl fish $(DOC) $(LIB) > \
105 | $(SHARE)/git-subrepo.fish
106 |
107 | clean:
108 | rm -fr tmp test/tmp
109 |
110 | define docker-make-test
111 | docker run --rm \
112 | -v $(PWD):/git-subrepo \
113 | -w /git-subrepo \
114 | $(DOCKER_IMAGE) \
115 | /bin/bash -c ' \
116 | set -x && \
117 | [[ -d /bash-$(1) ]] && \
118 | [[ -d /git-$(2) ]] && \
119 | export PATH=/bash-$(1)/bin:/git-$(2)/bin:$$PATH && \
120 | bash --version && \
121 | git --version && \
122 | make test prove=$(prove) test=$(test) \
123 | '
124 | endef
125 |
--------------------------------------------------------------------------------
/Meta:
--------------------------------------------------------------------------------
1 | =meta: 0.0.2
2 |
3 | name: git-subrepo
4 | version: 0.4.9
5 | abstract: Git Submodule Alternative
6 | homepage: https://github.com/ingydotnet/git-subrepo#readme
7 | license: MIT
8 | copyright: 2013-2024
9 |
10 | author:
11 | name: Ingy döt Net
12 | email: ingy@ingy.net
13 | github: ingydotnet
14 | twitter: ingydotnet
15 | freenode: ingy
16 | homepage: http://ingy.net
17 |
18 | requires:
19 | bash: 4.0.0
20 | git: 2.7.0
21 | test:
22 | cmd: make test
23 | install: make install
24 |
25 | devel:
26 | git: git@github.org:ingydotnet/git-subrepo.git
27 | irc: irc.freenode.net/gitcommands
28 | bug: https://github.com/ingydotnet/git-subrepo/issues/
29 |
--------------------------------------------------------------------------------
/doc/comparison.swim:
--------------------------------------------------------------------------------
1 | = Comparing `submodule` and `subrepo`
2 |
3 | This document compares Git's `submodule` command to the new `subrepo` command,
4 | with examples and discussion of all the common operations. I'll use the term
5 | "External" to mean the general concept of an external repo that might be used
6 | as a submodule or a subrepo.
7 |
8 | = Overview
9 |
10 |
11 |
12 | = Adding a new External
13 |
14 | As an owner or collaborator, you have decided to add a new External to your
15 | repo:
16 |
17 | - Submodule :: `git submodule add git@github.com/user/external`
18 | - Subtree :: `git subtree --squash --prefix=external git@github.com/user/external`
19 | - Subrepo :: `git subrepo clone git@github.com/user/external`
20 |
21 | /…to be completed…/
22 |
23 | = Updating from a changed External
24 |
25 | = Pushing External changes upstream
26 |
27 | = Moving/Renaming an External
28 |
29 | = Making an External on a branch
30 |
31 | = Changing the tracking branch of an External
32 |
33 | = Removing an External
34 |
35 | = Migration from One to the Other
36 |
--------------------------------------------------------------------------------
/ext/bashplus/.gitrepo:
--------------------------------------------------------------------------------
1 | ; DO NOT EDIT (unless you know what you are doing)
2 | ;
3 | ; This subdirectory is a git "subrepo", and this file is maintained by the
4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5 | ;
6 | [subrepo]
7 | remote = git@github.com:ingydotnet/bashplus.git
8 | branch = master
9 | commit = 030d196bf621e971e223e95e73c235e6992b85e0
10 | parent = 2c14be68fc5196ed1210d759421b33ef91c3e3db
11 | cmdver = 0.4.1
12 | method = merge
13 |
--------------------------------------------------------------------------------
/ext/bashplus/.travis.yml:
--------------------------------------------------------------------------------
1 | # C language gives closest shell env.
2 | language: c
3 |
4 | script:
5 | - git submodule update --init --recursive
6 | - PROVEOPT=-v make test
7 |
--------------------------------------------------------------------------------
/ext/bashplus/Changes:
--------------------------------------------------------------------------------
1 | ---
2 | version: 0.1.0
3 | date: Sat 14 Nov 2020 10:14:14 AM EST
4 | changes:
5 | - Add tests for version-check
6 | - Improve version-check
7 | - Move PATH assignment into test/setup
8 | - Meta bashplus supports Bash 3.2
9 | ---
10 | version: 0.0.9
11 | date: Wed 11 Nov 2020 02:19:32 PM EST
12 | changes:
13 | - Apply shellcheck fixes
14 | - Modernize bash code
15 | ---
16 | version: 0.0.8
17 | date: Fri Aug 21 08:00:45 PDT 2020
18 | changes:
19 | - Support paths with spaces @admorgan++
20 | ---
21 | version: 0.0.7
22 | date: Sat Jan 23 16:28:59 PST 2016
23 | changes:
24 | - Update tooling, and copyright
25 | ---
26 | version: 0.0.6
27 | date: Fri Jan 23 21:05:15 PST 2015
28 | changes:
29 | - Update tooling, and copyright
30 | ---
31 | version: 0.0.1
32 | date: Sun Oct 27 19:07:51 PDT 2013
33 | changes:
34 | - First release.
35 |
--------------------------------------------------------------------------------
/ext/bashplus/License:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright © 2013-2020 Ingy döt Net
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the ‘Software’), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ext/bashplus/Makefile:
--------------------------------------------------------------------------------
1 | ifeq ($(MAKECMDGOALS),install)
2 | ifeq "$(shell bpan version 2>/dev/null)" ""
3 | $(error 'BPAN not installed. See http://bpan.org')
4 | endif
5 | endif
6 |
7 | NAME := bash+
8 | LIB := lib/$(NAME).bash
9 | DOC := doc/$(NAME).swim
10 | MAN1 := man/man1
11 | MAN3 := man/man3
12 |
13 | INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
14 | INSTALL_DIR ?= test
15 | INSTALL_MAN1 ?= $(shell bpan env BPAN_MAN1)
16 | INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
17 |
18 | DOCKER_IMAGE := ingy/bash-testing:0.0.1
19 | DOCKER_TESTS := 5.1 5.0 4.4 4.3 4.2 4.1 4.0 3.2
20 | DOCKER_TESTS := $(DOCKER_TESTS:%=docker-test-%)
21 |
22 | default: help
23 |
24 | help:
25 | @echo 'Rules: test, install, doc'
26 |
27 | .PHONY: test
28 | test:
29 | prove $(PROVEOPT:%=% )test/
30 |
31 | test-all: test docker-test
32 |
33 | docker-test: $(DOCKER_TESTS)
34 |
35 | $(DOCKER_TESTS):
36 | $(call docker-make-test,$(@:docker-test-%=%))
37 |
38 | install:
39 | install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
40 | install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
41 | install -C -d -m 0755 $(INSTALL_MAN1)/
42 | install -C -d -m 0755 $(INSTALL_MAN3)/
43 | install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
44 | install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
45 |
46 | .PHONY: doc
47 | doc: ReadMe.pod $(MAN1)/$(NAME).1 $(MAN3)/$(NAME).3
48 |
49 | ReadMe.pod: $(DOC)
50 | swim --to=pod --complete --wrap $< > $@
51 |
52 | $(MAN1)/%.1: doc/%.swim
53 | swim --to=man $< > $@
54 |
55 | $(MAN3)/%.3: doc/%.swim
56 | swim --to=man $< > $@
57 |
58 | define docker-make-test
59 | docker run -i -t --rm \
60 | -v $(PWD):/git-subrepo \
61 | -w /git-subrepo \
62 | $(DOCKER_IMAGE) \
63 | /bin/bash -c ' \
64 | set -x && \
65 | [[ -d /bash-$(1) ]] && \
66 | export PATH=/bash-$(1)/bin:$$PATH && \
67 | bash --version && \
68 | make test \
69 | '
70 | endef
71 |
--------------------------------------------------------------------------------
/ext/bashplus/Meta:
--------------------------------------------------------------------------------
1 | =meta: 0.0.2
2 |
3 | name: bashplus
4 | version: 0.1.0
5 | abstract: Modern Bash Programming
6 | homepage: https://github.com/ingydotnet/bashplus
7 |
8 | license: MIT
9 | copyright: 2013-2020
10 | author:
11 | name: Ingy döt Net
12 | email: ingy@ingy.net
13 | github: ingydotnet
14 | twitter: ingydotnet
15 | freenode: ingy
16 | homepage: http://ingy.net
17 |
18 | requires:
19 | bash: 3.2
20 | test:
21 | cmd: make test
22 | install:
23 | cmd: make install
24 |
25 | devel:
26 | git: git@github.org/ingydotnet/bashplus
27 | irc: irc.freenode.net/bpan
28 | bug: https://github.com/ingydotnet/bashplus/issues/
29 |
--------------------------------------------------------------------------------
/ext/bashplus/ReadMe.pod:
--------------------------------------------------------------------------------
1 | =pod
2 |
3 | =for comment
4 | DO NOT EDIT. This Pod was generated by Swim v0.1.48.
5 | See http://github.com/ingydotnet/swim-pm#readme
6 |
7 | =encoding utf8
8 |
9 | =head1 Name
10 |
11 | Bash+(1) - Modern Bash Programming
12 |
13 | =for html
14 |
15 |
16 | =head1 Synopsis
17 |
18 | source bash+ :std :array
19 |
20 | use Foo::Bar this that
21 |
22 | Array.new args "$@"
23 |
24 | if args.empty?; then
25 | die "I need args!"
26 | fi
27 |
28 | Foo::Bar.new foo args
29 |
30 | this is awesome # <= this is a real command! (You just imported it)
31 |
32 | =head1 Description
33 |
34 | Bash+ is just Bash... B some libraries that can make Bash programming a
35 | lot nicer.
36 |
37 | =for comment # Installation
38 |
39 | Get the source code from GitHub:
40 |
41 | git clone git@github.com:ingydotnet/bashplus
42 |
43 | Then run:
44 |
45 | make test
46 | make install # Possibly with 'sudo'
47 |
48 | =head1 Usage
49 |
50 | For now look at some libraries the use Bash+:
51 |
52 | =over
53 |
54 | =item * L
55 |
56 | =item * L
57 |
58 | =item * L
59 |
60 | =back
61 |
62 | =head1 Status
63 |
64 | If you are interested in chatting about this, C on
65 | irc.freenode.net.
66 |
67 | =head1 Author
68 |
69 | Written by Ingy döt Net
70 |
71 | =head1 Copyright & License
72 |
73 | Copyright 2013-2020. Ingy döt Net.
74 |
75 | The MIT License (MIT).
76 |
77 | =cut
78 |
--------------------------------------------------------------------------------
/ext/bashplus/bin/bash+:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #------------------------------------------------------------------------------
3 | # Bash+ - Modern Bash Programming
4 | #
5 | # Copyright (c) 2013-2020 Ingy döt Net
6 | #------------------------------------------------------------------------------
7 |
8 | set -e
9 | shopt -s compat31 &>/dev/null || true
10 |
11 | #------------------------------------------------------------------------------
12 | # Determine how `bash+` was called, and do the right thing:
13 | #------------------------------------------------------------------------------
14 | if [[ ${BASH_SOURCE[0]} != "$0" ]]; then
15 | # 'bash+' is being sourced:
16 | [[ ${BASH_SOURCE[0]} =~ /bin/bash\\+$ ]] || {
17 | echo "Invalid Bash+ path '${BASH_SOURCE[0]}'" 2> /dev/null
18 | exit 1
19 | }
20 | source "${BASH_SOURCE[0]%/bin/*}"/lib/bash+.bash || return $?
21 | bash+:import "$@"
22 | return $?
23 |
24 | else
25 | if [[ $# -eq 1 ]] && [[ $1 == --version ]]; then
26 | echo 'bash+ version 0.0.9'
27 | else
28 | cat <<'...'
29 |
30 | Greetings modern Bash programmer. Welcome to Bash+!
31 |
32 | Bash+ is framework that makes Bash programming more like Ruby and Perl.
33 |
34 | See: https://github.com/bpan-org/bashplus
35 |
36 | If you got here trying to use bash+ in a program, you need to source it:
37 |
38 | source bash+
39 |
40 | Happy Bash Hacking!
41 |
42 | ...
43 | fi
44 | fi
45 |
--------------------------------------------------------------------------------
/ext/bashplus/doc/bash+.swim:
--------------------------------------------------------------------------------
1 | Bash+(1)
2 | ========
3 |
4 | Modern Bash Programming
5 |
6 |
7 |
8 | = Synopsis
9 |
10 | source bash+ :std :array
11 |
12 | use Foo::Bar this that
13 |
14 | Array.new args "$@"
15 |
16 | if args.empty?; then
17 | die "I need args!"
18 | fi
19 |
20 | Foo::Bar.new foo args
21 |
22 | this is awesome # <= this is a real command! (You just imported it)
23 |
24 | = Description
25 |
26 | Bash+ is just Bash... *plus* some libraries that can make Bash programming a
27 | lot nicer.
28 |
29 | ## Installation
30 |
31 | Get the source code from GitHub:
32 |
33 | git clone git@github.com:ingydotnet/bashplus
34 |
35 | Then run:
36 |
37 | make test
38 | make install # Possibly with 'sudo'
39 |
40 | = Usage
41 |
42 | For now look at some libraries the use Bash+:
43 |
44 | * https://github.com/ingydotnet/git-hub
45 | * https://github.com/ingydotnet/json-bash
46 | * https://github.com/ingydotnet/test-more-bash
47 |
48 | = Status
49 |
50 | If you are interested in chatting about this, `/join #bpan` on
51 | irc.freenode.net.
52 |
53 | = Author
54 |
55 | Written by Ingy döt Net
56 |
57 | = Copyright & License
58 |
59 | Copyright 2013-2020. Ingy döt Net.
60 |
61 | The MIT License (MIT).
62 |
--------------------------------------------------------------------------------
/ext/bashplus/lib/bash+.bash:
--------------------------------------------------------------------------------
1 | # bash+ - Modern Bash Programming
2 | #
3 | # Copyright (c) 2013-2020 Ingy döt Net
4 |
5 | set -e
6 |
7 | [[ ${BASHPLUS_VERSION-} ]] && return 0
8 |
9 | BASHPLUS_VERSION=0.1.0
10 |
11 | bash+:version-check() {
12 | local cmd want got out
13 |
14 | IFS=' ' read -r -a cmd <<< "${1:?}"
15 | IFS=. read -r -a want <<< "${2:?}"
16 | : "${want[0]:=0}"
17 | : "${want[1]:=0}"
18 | : "${want[2]:=0}"
19 |
20 | if [[ ${cmd[*]} == bash ]]; then
21 | got=("${BASH_VERSINFO[@]}")
22 | BASHPLUS_VERSION_CHECK=${BASH_VERSION-}
23 | else
24 | [[ ${#cmd[*]} -gt 1 ]] || cmd+=(--version)
25 | out=$("${cmd[@]}") ||
26 | { echo "Failed to run '${cmd[*]}'" >&2; exit 1; }
27 | [[ $out =~ ([0-9]+\.[0-9]+(\.[0-9]+)?) ]] ||
28 | { echo "Can't determine version number from '${cmd[*]}'" >&2; exit 1; }
29 | BASHPLUS_VERSION_CHECK=${BASH_REMATCH[1]}
30 | IFS=. read -r -a got <<< "$BASHPLUS_VERSION_CHECK"
31 | fi
32 | : "${got[2]:=0}"
33 |
34 | (( got[0] > want[0] || ((
35 | got[0] == want[0] && ((
36 | got[1] > want[1] || ((
37 | got[1] == want[1] && got[2] >= want[2]
38 | )) )) )) ))
39 | }
40 |
41 | bash+:version-check bash 3.2 ||
42 | { echo "The 'bashplus' library requires 'Bash 3.2+'." >&2; exit 1; }
43 |
44 | @() (echo "$@") # XXX do we want to keep this?
45 |
46 | bash+:export:std() {
47 | set -o pipefail
48 |
49 | if bash+:version-check bash 4.4; then
50 | set -o nounset
51 | shopt -s inherit_errexit
52 | fi
53 |
54 | echo use die warn
55 | }
56 |
57 | # Source a bash library call import on it:
58 | bash+:use() {
59 | local library_name=${1:?bash+:use requires library name}; shift
60 | local library_path=; library_path=$(bash+:findlib "$library_name") || true
61 | [[ $library_path ]] ||
62 | bash+:die "Can't find library '$library_name'." 1
63 |
64 | source "$library_path"
65 | if bash+:can "$library_name:import"; then
66 | "$library_name:import" "$@"
67 | else
68 | bash+:import "$@"
69 | fi
70 | }
71 |
72 | # Copy bash+: functions to unprefixed functions
73 | bash+:import() {
74 | local arg=
75 | for arg; do
76 | if [[ $arg =~ ^: ]]; then
77 | # Word splitting required here
78 | # shellcheck disable=2046
79 | bash+:import $(bash+:export"$arg")
80 | else
81 | bash+:fcopy "bash+:$arg" "$arg"
82 | fi
83 | done
84 | }
85 |
86 | # Function copy
87 | bash+:fcopy() {
88 | bash+:can "${1:?bash+:fcopy requires an input function name}" ||
89 | bash+:die "'$1' is not a function" 2
90 | local func
91 | func=$(type "$1" 3>/dev/null | tail -n+3)
92 | [[ ${3-} ]] && "$3"
93 | eval "${2:?bash+:fcopy requires an output function name}() $func"
94 | }
95 |
96 | # Find the path of a library
97 | bash+:findlib() {
98 | local library_name
99 | library_name=$(tr '[:upper:]' '[:lower:]' <<< "${1//:://}").bash
100 | local lib=${BASHPLUSLIB:-${BASHLIB:-$PATH}}
101 | library_name=${library_name//+/\\+}
102 | IFS=':' read -r -a libs <<< "$lib"
103 | find "${libs[@]}" -name "${library_name##*/}" 2>/dev/null |
104 | grep -E "$library_name\$" |
105 | head -n1
106 | }
107 |
108 | bash+:die() {
109 | local msg=${1:-Died}
110 | msg=${msg//\\n/$'\n'}
111 |
112 | printf "%s" "$msg" >&2
113 | if [[ $msg == *$'\n' ]]; then
114 | exit 1
115 | else
116 | printf "\n"
117 | fi
118 |
119 | local c
120 | IFS=' ' read -r -a c <<< "$(caller "${DIE_STACK_LEVEL:-${2:-0}}")"
121 | if (( ${#c[@]} == 2 )); then
122 | msg=" at line %d of %s"
123 | else
124 | msg=" at line %d in %s of %s"
125 | fi
126 |
127 | # shellcheck disable=2059
128 | printf "$msg\n" "${c[@]}" >&2
129 | exit 1
130 | }
131 |
132 | bash+:warn() {
133 | local msg=${1:-Warning}
134 | printf "%s" "${msg//\\n/$'\n'}\n" >&2
135 | }
136 |
137 | bash+:can() {
138 | [[ $(type -t "${1:?bash+:can requires a function name}") == function ]]
139 | }
140 |
--------------------------------------------------------------------------------
/ext/bashplus/man/man1/bash+.1:
--------------------------------------------------------------------------------
1 | .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
2 | .\"
3 | .\" Standard preamble:
4 | .\" ========================================================================
5 | .de Sp \" Vertical space (when we can't use .PP)
6 | .if t .sp .5v
7 | .if n .sp
8 | ..
9 | .de Vb \" Begin verbatim text
10 | .ft CW
11 | .nf
12 | .ne \\$1
13 | ..
14 | .de Ve \" End verbatim text
15 | .ft R
16 | .fi
17 | ..
18 | .\" Set up some character translations and predefined strings. \*(-- will
19 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 | .\" nothing in troff, for use with C<>.
24 | .tr \(*W-
25 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 | .ie n \{\
27 | . ds -- \(*W-
28 | . ds PI pi
29 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 | . ds L" ""
32 | . ds R" ""
33 | . ds C` ""
34 | . ds C' ""
35 | 'br\}
36 | .el\{\
37 | . ds -- \|\(em\|
38 | . ds PI \(*p
39 | . ds L" ``
40 | . ds R" ''
41 | . ds C`
42 | . ds C'
43 | 'br\}
44 | .\"
45 | .\" Escape single quotes in literal strings from groff's Unicode transform.
46 | .ie \n(.g .ds Aq \(aq
47 | .el .ds Aq '
48 | .\"
49 | .\" If the F register is >0, we'll generate index entries on stderr for
50 | .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 | .\" entries marked with X<> in POD. Of course, you'll have to process the
52 | .\" output yourself in some meaningful fashion.
53 | .\"
54 | .\" Avoid warning from groff about undefined register 'F'.
55 | .de IX
56 | ..
57 | .nr rF 0
58 | .if \n(.g .if rF .nr rF 1
59 | .if (\n(rF:(\n(.g==0)) \{\
60 | . if \nF \{\
61 | . de IX
62 | . tm Index:\\$1\t\\n%\t"\\$2"
63 | ..
64 | . if !\nF==2 \{\
65 | . nr % 0
66 | . nr F 2
67 | . \}
68 | . \}
69 | .\}
70 | .rr rF
71 | .\" ========================================================================
72 | .\"
73 | .IX Title "STDIN 1"
74 | .TH STDIN 1 "November 2020" "Generated by Swim v0.1.48" "Modern Bash Programming"
75 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
76 | .\" way too many mistakes in technical documents.
77 | .if n .ad l
78 | .nh
79 | .SH "Name"
80 | .IX Header "Name"
81 | Bash+(1) \- Modern Bash Programming
82 | .SH "Synopsis"
83 | .IX Header "Synopsis"
84 | .Vb 1
85 | \& source bash+ :std :array
86 | \&
87 | \& use Foo::Bar this that
88 | \&
89 | \& Array.new args "$@"
90 | \&
91 | \& if args.empty?; then
92 | \& die "I need args!"
93 | \& fi
94 | \&
95 | \& Foo::Bar.new foo args
96 | \&
97 | \& this is awesome # <= this is a real command! (You just imported it)
98 | .Ve
99 | .SH "Description"
100 | .IX Header "Description"
101 | Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
102 | .PP
103 | Get the source code from GitHub:
104 | .PP
105 | .Vb 1
106 | \& git clone git@github.com:ingydotnet/bashplus
107 | .Ve
108 | .PP
109 | Then run:
110 | .PP
111 | .Vb 2
112 | \& make test
113 | \& make install # Possibly with \*(Aqsudo\*(Aq
114 | .Ve
115 | .SH "Usage"
116 | .IX Header "Usage"
117 | For now look at some libraries the use Bash+:
118 | .IP "\(bu" 4
119 |
120 | .IP "\(bu" 4
121 |
122 | .IP "\(bu" 4
123 |
124 | .SH "Status"
125 | .IX Header "Status"
126 | If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
127 | .SH "Author"
128 | .IX Header "Author"
129 | Written by Ingy döt Net
130 | .SH "Copyright & License"
131 | .IX Header "Copyright & License"
132 | Copyright 2013\-2020. Ingy döt Net.
133 | .PP
134 | The \s-1MIT\s0 License (\s-1MIT\s0).
135 |
--------------------------------------------------------------------------------
/ext/bashplus/man/man3/bash+.3:
--------------------------------------------------------------------------------
1 | .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
2 | .\"
3 | .\" Standard preamble:
4 | .\" ========================================================================
5 | .de Sp \" Vertical space (when we can't use .PP)
6 | .if t .sp .5v
7 | .if n .sp
8 | ..
9 | .de Vb \" Begin verbatim text
10 | .ft CW
11 | .nf
12 | .ne \\$1
13 | ..
14 | .de Ve \" End verbatim text
15 | .ft R
16 | .fi
17 | ..
18 | .\" Set up some character translations and predefined strings. \*(-- will
19 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 | .\" nothing in troff, for use with C<>.
24 | .tr \(*W-
25 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 | .ie n \{\
27 | . ds -- \(*W-
28 | . ds PI pi
29 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 | . ds L" ""
32 | . ds R" ""
33 | . ds C` ""
34 | . ds C' ""
35 | 'br\}
36 | .el\{\
37 | . ds -- \|\(em\|
38 | . ds PI \(*p
39 | . ds L" ``
40 | . ds R" ''
41 | . ds C`
42 | . ds C'
43 | 'br\}
44 | .\"
45 | .\" Escape single quotes in literal strings from groff's Unicode transform.
46 | .ie \n(.g .ds Aq \(aq
47 | .el .ds Aq '
48 | .\"
49 | .\" If the F register is >0, we'll generate index entries on stderr for
50 | .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 | .\" entries marked with X<> in POD. Of course, you'll have to process the
52 | .\" output yourself in some meaningful fashion.
53 | .\"
54 | .\" Avoid warning from groff about undefined register 'F'.
55 | .de IX
56 | ..
57 | .nr rF 0
58 | .if \n(.g .if rF .nr rF 1
59 | .if (\n(rF:(\n(.g==0)) \{\
60 | . if \nF \{\
61 | . de IX
62 | . tm Index:\\$1\t\\n%\t"\\$2"
63 | ..
64 | . if !\nF==2 \{\
65 | . nr % 0
66 | . nr F 2
67 | . \}
68 | . \}
69 | .\}
70 | .rr rF
71 | .\" ========================================================================
72 | .\"
73 | .IX Title "STDIN 1"
74 | .TH STDIN 1 "November 2020" "Generated by Swim v0.1.48" "Modern Bash Programming"
75 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
76 | .\" way too many mistakes in technical documents.
77 | .if n .ad l
78 | .nh
79 | .SH "Name"
80 | .IX Header "Name"
81 | Bash+(1) \- Modern Bash Programming
82 | .SH "Synopsis"
83 | .IX Header "Synopsis"
84 | .Vb 1
85 | \& source bash+ :std :array
86 | \&
87 | \& use Foo::Bar this that
88 | \&
89 | \& Array.new args "$@"
90 | \&
91 | \& if args.empty?; then
92 | \& die "I need args!"
93 | \& fi
94 | \&
95 | \& Foo::Bar.new foo args
96 | \&
97 | \& this is awesome # <= this is a real command! (You just imported it)
98 | .Ve
99 | .SH "Description"
100 | .IX Header "Description"
101 | Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
102 | .PP
103 | Get the source code from GitHub:
104 | .PP
105 | .Vb 1
106 | \& git clone git@github.com:ingydotnet/bashplus
107 | .Ve
108 | .PP
109 | Then run:
110 | .PP
111 | .Vb 2
112 | \& make test
113 | \& make install # Possibly with \*(Aqsudo\*(Aq
114 | .Ve
115 | .SH "Usage"
116 | .IX Header "Usage"
117 | For now look at some libraries the use Bash+:
118 | .IP "\(bu" 4
119 |
120 | .IP "\(bu" 4
121 |
122 | .IP "\(bu" 4
123 |
124 | .SH "Status"
125 | .IX Header "Status"
126 | If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
127 | .SH "Author"
128 | .IX Header "Author"
129 | Written by Ingy döt Net
130 | .SH "Copyright & License"
131 | .IX Header "Copyright & License"
132 | Copyright 2013\-2020. Ingy döt Net.
133 | .PP
134 | The \s-1MIT\s0 License (\s-1MIT\s0).
135 |
--------------------------------------------------------------------------------
/ext/bashplus/test/base.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+ :std
6 |
7 | ok $? "'source bash+' works"
8 |
9 | is "$BASHPLUS_VERSION" '0.1.0' 'BASHPLUS_VERSION is 0.1.0'
10 |
11 | done_testing 2
12 |
--------------------------------------------------------------------------------
/ext/bashplus/test/die.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+ :std
6 |
7 | got=$(die "Nope" 2>&1) || true
8 | want="Nope
9 | at line 7 in main of test/die.t"
10 | is "$got" "$want" "die() msg ok"
11 |
12 | got=$(die "Nope\n" 2>&1) || true
13 | want="Nope"
14 | is "$got" "$want" "die() msg ok"
15 |
16 | done_testing 2
17 |
--------------------------------------------------------------------------------
/ext/bashplus/test/fcopy.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+
6 |
7 | foo() {
8 | echo O HAI
9 | }
10 |
11 | like "$(type bar 2>&1)" 'bar: not found' \
12 | 'bar is not yet a function'
13 |
14 | bash+:fcopy foo bar
15 |
16 | type -t bar &>/dev/null
17 | ok $? 'bar is now a function'
18 | is "$(type foo | tail -n+3)" "$(type bar | tail -n+3)" \
19 | 'Copy matches original'
20 |
21 | done_testing 3
22 |
--------------------------------------------------------------------------------
/ext/bashplus/test/lib/foo/bar.bash:
--------------------------------------------------------------------------------
1 | Foo__Bar_VERSION='1.2.3'
2 |
3 | Foo::Bar:baz() { :;}
4 |
--------------------------------------------------------------------------------
/ext/bashplus/test/lib/foo/foo.bash:
--------------------------------------------------------------------------------
1 | Foo::Foo:import() {
2 | echo $1---$2
3 | }
4 |
--------------------------------------------------------------------------------
/ext/bashplus/test/setup:
--------------------------------------------------------------------------------
1 | # shellcheck shell=bash
2 |
3 | #------------------------------------------------------------------------------
4 | # This is a tiny version of test-more-bash that I use here. test-more-bash uses
5 | # bash+, so I want to avoid the circular dependency. This little guy does
6 | # 80-90% what test-more-bash does, with minimal code. It's a good example of
7 | # how nice Bash can be.
8 | #------------------------------------------------------------------------------
9 |
10 | set -e -o pipefail
11 |
12 | PATH=$PWD/bin:$PATH
13 |
14 | run=0
15 |
16 | plan() {
17 | echo "1..$1"
18 | }
19 |
20 | pass() {
21 | (( ++run ))
22 | echo "ok $run${1:+ - $1}"
23 | }
24 |
25 | fail() {
26 | (( ++run ))
27 | echo "not ok $run${1:+ - $1}"
28 | }
29 |
30 | is() {
31 | if [[ $1 == "$2" ]]; then
32 | pass "$3"
33 | else
34 | fail "$3"
35 | diag "Got: $1"
36 | diag "Want: $2"
37 | fi
38 | }
39 |
40 | ok() {
41 | if (exit "${1:-$?}"); then
42 | pass "$2"
43 | else
44 | fail "$2"
45 | fi
46 | }
47 |
48 | like() {
49 | if [[ $1 =~ $2 ]]; then
50 | pass "$3"
51 | else
52 | fail "$3"
53 | diag "Got: $1"
54 | diag "Like: $2"
55 | fi
56 | }
57 |
58 | unlike() {
59 | if [[ ! $1 =~ $2 ]]; then
60 | pass "$3"
61 | else
62 | fail "$3"
63 | diag "Got: $1"
64 | diag "Dont: $2"
65 | fi
66 | }
67 |
68 | done_testing() {
69 | echo "1..${1:-$run}"
70 | }
71 |
72 | diag() {
73 | echo "# ${1//$'\n'/$'\n'# }" >&2
74 | }
75 |
76 | note() {
77 | echo "# ${1//$'\n'/$'\n'# }"
78 | }
79 |
80 | #! vim: ft=sh sw=2:
81 |
--------------------------------------------------------------------------------
/ext/bashplus/test/shellcheck.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+
6 |
7 | if ! command -v shellcheck >/dev/null; then
8 | plan skip_all "The 'shellcheck' utility is not installed"
9 | fi
10 | if [[ ! $(shellcheck --version) =~ 0\.7\.1 ]]; then
11 | plan skip_all "This test wants shellcheck version 0.7.1"
12 | fi
13 |
14 | IFS=$'\n' read -d '' -r -a shell_files <<< "$(
15 | find bin -type f
16 | find lib -type f
17 | echo test/setup
18 | find test -name '*.t'
19 | )" || true
20 |
21 | skips=(
22 | # We want to keep these 2 here always:
23 | SC1090 # Can't follow non-constant source. Use a directive to specify location.
24 | SC1091 # Not following: bash+ was not specified as input (see shellcheck -x).
25 | )
26 |
27 | skip=$(IFS=,; echo "${skips[*]}")
28 |
29 | for file in "${shell_files[@]}"; do
30 | [[ $file == *swp ]] && continue
31 | is "$(shellcheck -e "$skip" "$file")" "" \
32 | "The shell file '$file' passes shellcheck"
33 | done
34 |
35 | done_testing
36 |
37 | # vim: set ft=sh:
38 |
--------------------------------------------------------------------------------
/ext/bashplus/test/source-bash+-std.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+ :std
6 |
7 | ok "$(bash+:can use)" 'use is imported'
8 | ok "$(bash+:can die)" 'die is imported'
9 | ok "$(bash+:can warn)" 'warn is imported'
10 |
11 | ok "$(! bash+:can import)" 'import is not imported'
12 | ok "$(! bash+:can main)" 'main is not imported'
13 | ok "$(! bash+:can fcopy)" 'fcopy is not imported'
14 | ok "$(! bash+:can findlib)" 'findlib is not imported'
15 | ok "$(! bash+:can can)" 'can is not imported'
16 |
17 | done_testing 8
18 |
--------------------------------------------------------------------------------
/ext/bashplus/test/source-bash+.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+
6 |
7 | functions=(
8 | use
9 | import
10 | fcopy
11 | findlib
12 | die
13 | warn
14 | can
15 | )
16 |
17 | for f in "${functions[@]}"; do
18 | is "$(type -t "bash+:$f")" function \
19 | "bash+:$f is a function"
20 | done
21 |
22 | done_testing 7
23 |
--------------------------------------------------------------------------------
/ext/bashplus/test/use.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | source bash+ :std can
6 |
7 | # shellcheck disable=2034
8 | BASHLIB=test/lib
9 |
10 | use Foo::Bar
11 |
12 | ok $? 'use Foo::Bar - works'
13 | ok "$(can Foo::Bar:baz)" 'Function Foo::Bar:baz exists'
14 |
15 | # shellcheck disable=2016,2154
16 | is "$Foo__Bar_VERSION" 1.2.3 '$Foo__Bar_VERSION == 1.2.3'
17 |
18 | output=$(use Foo::Foo Boo Booo)
19 | ok $? 'use Foo::Foo Boo Booo - works'
20 | is "$output" Boo---Booo 'Correct import called'
21 |
22 | done_testing 5
23 |
--------------------------------------------------------------------------------
/ext/bashplus/test/version-check.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+ version-check
7 |
8 | t1() (echo 0.1.2)
9 | t2() (echo 0.1)
10 |
11 | ok "$(version-check t1 0)" "0.1.2 >= 0"
12 | ok "$(version-check t1 0.1)" "0.1.2 >= 0.1"
13 | ok "$(version-check t1 0.1.1)" "0.1.2 >= 0.1.1"
14 | ok "$(version-check t1 0.1.2)" "0.1.2 >= 0.1.2"
15 | ok "$(! version-check t1 0.2)" "0.1.2 >= 0.2 fails"
16 | ok "$(! version-check t1 0.1.3)" "0.1.2 >= 0.1.3 fails"
17 |
18 | ok "$(version-check t2 0)" "0.1 >= 0"
19 | ok "$(version-check t2 0.1)" "0.1 >= 0.1"
20 | ok "$(! version-check t2 0.2)" "0.1 >= 0.2 fails"
21 | ok "$(! version-check t2 0.1.1)" "0.1 >= 0.1.1"
22 |
23 | done_testing 10
24 |
--------------------------------------------------------------------------------
/ext/test-more-bash/.gitrepo:
--------------------------------------------------------------------------------
1 | ; DO NOT EDIT (unless you know what you are doing)
2 | ;
3 | ; This subdirectory is a git "subrepo", and this file is maintained by the
4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5 | ;
6 | [subrepo]
7 | remote = git@github.com:ingydotnet/test-more-bash.git
8 | branch = master
9 | commit = c7df24fcb0814fbb62a33d92dc3c8d526ff710f0
10 | parent = 914c2ae8e3b881f62ca987c1c3343df6a034d865
11 | cmdver = 0.4.1
12 | method = merge
13 |
--------------------------------------------------------------------------------
/ext/test-more-bash/.travis.yml:
--------------------------------------------------------------------------------
1 | # C language gives closest shell env.
2 | language: c
3 |
4 | script:
5 | - git submodule update --init --recursive
6 | - PROVEOPT=-v make test
7 |
--------------------------------------------------------------------------------
/ext/test-more-bash/Changes:
--------------------------------------------------------------------------------
1 | ---
2 | version: 0.0.5
3 | date: Wed 11 Nov 2020 02:33:42 PM EST
4 | changes:
5 | - Refactor to modern bash
6 | ---
7 | version: 0.0.4
8 | date: Fri Sep 4 12:26:58 2020 -0700
9 | changes:
10 | - Make up to date
11 | - Apply a few PRs
12 | ---
13 | version: 0.0.3
14 | date: Sat Jan 23 16:39:20 PST 2016
15 | changes:
16 | - Make up to date
17 | ---
18 | version: 0.0.2
19 | date: Fri Jan 23 21:26:18 PST 2015
20 | changes:
21 | - Make up to date
22 | ---
23 | version: 0.0.1
24 | date: Sun Oct 27 22:53:10 PDT 2013
25 | changes:
26 | - First release.
27 |
--------------------------------------------------------------------------------
/ext/test-more-bash/License:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright © 2013-2020. Ingy döt Net.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the ‘Software’), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ext/test-more-bash/Makefile:
--------------------------------------------------------------------------------
1 | NAME := test-more
2 | DOC := doc/$(NAME).swim
3 | MAN3 := man/man3
4 |
5 | DOCKER_IMAGE := ingy/bash-testing:0.0.1
6 | DOCKER_TESTS := 5.1 5.0 4.4 4.3 4.2 4.1 4.0 3.2
7 | DOCKER_TESTS := $(DOCKER_TESTS:%=docker-test-%)
8 |
9 | default: help
10 |
11 | help:
12 | @echo 'Rules: test, doc'
13 |
14 | .PHONY: test
15 | test:
16 | prove $(PROVEOPT:%=% )test/
17 |
18 | test-all: test docker-test
19 |
20 | docker-test: $(DOCKER_TESTS)
21 |
22 | $(DOCKER_TESTS):
23 | $(call docker-make-test,$(@:docker-test-%=%))
24 |
25 | doc: ReadMe.pod $(MAN3)/$(NAME).3
26 |
27 | ReadMe.pod: $(DOC)
28 | swim --to=pod --complete --wrap $< > $@
29 |
30 | $(MAN3)/%.3: doc/%.swim
31 | swim --to=man $< > $@
32 |
33 | define docker-make-test
34 | docker run -i -t --rm \
35 | -v $(PWD):/git-subrepo \
36 | -w /git-subrepo \
37 | $(DOCKER_IMAGE) \
38 | /bin/bash -c ' \
39 | set -x && \
40 | [[ -d /bash-$(1) ]] && \
41 | export PATH=/bash-$(1)/bin:$$PATH && \
42 | bash --version && \
43 | make test \
44 | '
45 | endef
46 |
--------------------------------------------------------------------------------
/ext/test-more-bash/Meta:
--------------------------------------------------------------------------------
1 | =meta: 0.0.2
2 |
3 | name: test-more
4 | version: 0.0.5
5 | abstract: TAP Testing for Bash
6 | homepage: http://bpan.org/package/test-more/
7 |
8 | license: MIT
9 | copyright: 2013-2020
10 | author:
11 | name: Ingy döt Net
12 | email: ingy@ingy.net
13 | github: ingydotnet
14 | twitter: ingydotnet
15 | freenode: ingy
16 | homepage: http://ingy.net
17 |
18 | requires:
19 | bash: 4.4.0
20 | bashplus: 0.0.9
21 | test-tap: 0.0.5
22 | test:
23 | cmd: make test
24 | install:
25 | cmd: make install
26 |
27 | devel:
28 | git: git@github.org/ingydotnet/test-more-bash.git
29 | irc: irc.freenode.net#bpan
30 | bug: https://github.com/ingydotnet/test-more-bash/issues/
31 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ReadMe.pod:
--------------------------------------------------------------------------------
1 | =pod
2 |
3 | =for comment
4 | DO NOT EDIT. This Pod was generated by Swim v0.1.48.
5 | See http://github.com/ingydotnet/swim-pm#readme
6 |
7 | =encoding utf8
8 |
9 | =head1 Name
10 |
11 | Test::More - TAP Testing for Bash
12 |
13 | =for html
14 |
15 |
16 | =head1 Synopsis
17 |
18 | Write a test file like this. Maybe call it C:
19 |
20 | #!/usr/bin/env bash
21 |
22 | TEST_MORE_PATH="/path/to/test-more-bash"
23 | BASHLIB="`
24 | find $TEST_MORE_PATH -type d |
25 | grep -E '/(bin|lib)$' |
26 | xargs -n1 printf "%s:"`"
27 | PATH="$BASHLIB$PATH"
28 |
29 | source bash+ :std
30 |
31 | use Test::More
32 |
33 | plan tests 8
34 |
35 | some-command
36 | ok $? 'some-command is ok'
37 |
38 | # or:
39 | ok "`some-command`" 'some-command is ok'
40 |
41 | pass 'This will always pass'
42 |
43 | fail 'This will always fail'
44 |
45 | is `echo foo` 'foo' 'foo is foo'
46 |
47 | isnt foo bar "foo isn't bar"
48 |
49 | like food foo 'food is like foo'
50 |
51 | unlike team I "There's no 'I' in 'team'"
52 |
53 | diag "A message for stderr"
54 |
55 | note "A message for stdout"
56 |
57 | output=( $(ls) )
58 | expected=(README lib bin)
59 | cmp-array output expected "list files"
60 |
61 | Run the test with C like this:
62 |
63 | prove test/test.t
64 |
65 | Prove knows it's Bash from the first line (the hashbang), and it just works.
66 |
67 | =head1 Description
68 |
69 | Test::More is the tried and true testing library for Perl. It uses TAP (the
70 | Test Anything Protocol). This is the same thing for Bash. For the most part it
71 | should work exactly the same.
72 |
73 | =head1 Methods
74 |
75 | This is the basic usage:
76 |
77 | =over
78 |
79 | =item * C
80 |
81 | =item * C
82 |
83 | =item * C
84 |
85 | =item * C
86 |
87 | =item * C
88 |
89 | =item * C
90 |
91 | =item * C
92 |
93 | =item * C
94 |
95 | =item * C
96 |
97 | =item * C
98 |
99 | =item * C
100 |
101 | =item * C
102 |
103 | =item * C
104 |
105 | =item * `cmp-array output expected "message"
106 |
107 | =back
108 |
109 | More detailed info coming soon.
110 |
111 | =head1 Author
112 |
113 | Ingy döt Net
114 |
115 | =head1 Copyright & License
116 |
117 | Copyright 2013-2020. Ingy döt Net.
118 |
119 | The MIT License (MIT)
120 |
121 | =cut
122 |
--------------------------------------------------------------------------------
/ext/test-more-bash/doc/test-more.swim:
--------------------------------------------------------------------------------
1 | Test::More
2 | ==========
3 |
4 | TAP Testing for Bash
5 |
6 |
7 |
8 | = Synopsis
9 |
10 | Write a test file like this. Maybe call it `test/test.t`:
11 |
12 | #!/usr/bin/env bash
13 |
14 | TEST_MORE_PATH="/path/to/test-more-bash"
15 | BASHLIB="`
16 | find $TEST_MORE_PATH -type d |
17 | grep -E '/(bin|lib)$' |
18 | xargs -n1 printf "%s:"`"
19 | PATH="$BASHLIB$PATH"
20 |
21 | source bash+ :std
22 |
23 | use Test::More
24 |
25 | plan tests 8
26 |
27 | some-command
28 | ok $? 'some-command is ok'
29 |
30 | # or:
31 | ok "`some-command`" 'some-command is ok'
32 |
33 | pass 'This will always pass'
34 |
35 | fail 'This will always fail'
36 |
37 | is `echo foo` 'foo' 'foo is foo'
38 |
39 | isnt foo bar "foo isn't bar"
40 |
41 | like food foo 'food is like foo'
42 |
43 | unlike team I "There's no 'I' in 'team'"
44 |
45 | diag "A message for stderr"
46 |
47 | note "A message for stdout"
48 |
49 | output=( $(ls) )
50 | expected=(README lib bin)
51 | cmp-array output expected "list files"
52 |
53 | Run the test with `prove` like this:
54 |
55 | prove test/test.t
56 |
57 | Prove knows it's Bash from the first line (the hashbang), and it just works.
58 |
59 | = Description
60 |
61 | Test::More is the tried and true testing library for Perl. It uses TAP (the
62 | Test Anything Protocol). This is the same thing for Bash. For the most part it
63 | should work exactly the same.
64 |
65 | = Methods
66 |
67 | This is the basic usage:
68 |
69 | * `plan tests $count`
70 | * `ok $status_code "$label"`
71 | * `pass "$label"`
72 | * `fail "$label"`
73 | * `is "$got" "$want" "label"`
74 | * `isnt "$got" "$unwanted" "$label"`
75 | * `like "$got" "$regex" "$label"`
76 | * `unlike "$got" "$regex" "$label"`
77 | * `diag "$message"`
78 | * `note "$message"`
79 | * `done_testing $count`
80 | * `plan skip_all "$reason"`
81 | * `BAIL_OUT "$reason"`
82 | * `cmp-array output expected "message"
83 |
84 | More detailed info coming soon.
85 |
86 | = Author
87 |
88 | Ingy döt Net
89 |
90 | = Copyright & License
91 |
92 | Copyright 2013-2020. Ingy döt Net.
93 |
94 | The MIT License (MIT)
95 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/.gitrepo:
--------------------------------------------------------------------------------
1 | ; DO NOT EDIT (unless you know what you are doing)
2 | ;
3 | ; This subdirectory is a git "subrepo", and this file is maintained by the
4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5 | ;
6 | [subrepo]
7 | remote = git@github.com:ingydotnet/bashplus.git
8 | branch = master
9 | commit = e49f45a1457fed3cceb15bd4a82b0f7515efd8e5
10 | parent = c978e2afd6861203138f28d0021e03fa1ffbba0c
11 | cmdver = 0.4.1
12 | method = merge
13 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/.travis.yml:
--------------------------------------------------------------------------------
1 | # C language gives closest shell env.
2 | language: c
3 |
4 | script:
5 | - git submodule update --init --recursive
6 | - PROVEOPT=-v make test
7 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/Changes:
--------------------------------------------------------------------------------
1 | ---
2 | version: 0.0.9
3 | date: Wed 11 Nov 2020 02:19:32 PM EST
4 | changes:
5 | - Apply shellcheck fixes
6 | - Modernize bash code
7 | ---
8 | version: 0.0.8
9 | date: Fri Aug 21 08:00:45 PDT 2020
10 | changes:
11 | - Support paths with spaces @admorgan++
12 | ---
13 | version: 0.0.7
14 | date: Sat Jan 23 16:28:59 PST 2016
15 | changes:
16 | - Update tooling, and copyright
17 | ---
18 | version: 0.0.6
19 | date: Fri Jan 23 21:05:15 PST 2015
20 | changes:
21 | - Update tooling, and copyright
22 | ---
23 | version: 0.0.1
24 | date: Sun Oct 27 19:07:51 PDT 2013
25 | changes:
26 | - First release.
27 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/License:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright © 2013-2020 Ingy döt Net
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the ‘Software’), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/Makefile:
--------------------------------------------------------------------------------
1 | ifeq ($(MAKECMDGOALS),install)
2 | ifeq "$(shell bpan version 2>/dev/null)" ""
3 | $(error 'BPAN not installed. See http://bpan.org')
4 | endif
5 | endif
6 |
7 | NAME := bash+
8 | LIB := lib/$(NAME).bash
9 | DOC := doc/$(NAME).swim
10 | MAN1 := man/man1
11 | MAN3 := man/man3
12 |
13 | INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
14 | INSTALL_DIR ?= test
15 | INSTALL_MAN1 ?= $(shell bpan env BPAN_MAN1)
16 | INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
17 |
18 | DOCKER_IMAGE := ingy/bash-testing:0.0.1
19 | DOCKER_TESTS := 5.1 5.0 4.4 4.3 4.2 4.1 4.0 3.2
20 | DOCKER_TESTS := $(DOCKER_TESTS:%=docker-test-%)
21 |
22 | default: help
23 |
24 | help:
25 | @echo 'Rules: test, install, doc'
26 |
27 | .PHONY: test
28 | test:
29 | prove $(PROVEOPT:%=% )test/
30 |
31 | test-all: test docker-test
32 |
33 | docker-test: $(DOCKER_TESTS)
34 |
35 | $(DOCKER_TESTS):
36 | $(call docker-make-test,$(@:docker-test-%=%))
37 |
38 | install:
39 | install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
40 | install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
41 | install -C -d -m 0755 $(INSTALL_MAN1)/
42 | install -C -d -m 0755 $(INSTALL_MAN3)/
43 | install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
44 | install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
45 |
46 | .PHONY: doc
47 | doc: ReadMe.pod $(MAN1)/$(NAME).1 $(MAN3)/$(NAME).3
48 |
49 | ReadMe.pod: $(DOC)
50 | swim --to=pod --complete --wrap $< > $@
51 |
52 | $(MAN1)/%.1: doc/%.swim
53 | swim --to=man $< > $@
54 |
55 | $(MAN3)/%.3: doc/%.swim
56 | swim --to=man $< > $@
57 |
58 | define docker-make-test
59 | docker run -i -t --rm \
60 | -v $(PWD):/git-subrepo \
61 | -w /git-subrepo \
62 | $(DOCKER_IMAGE) \
63 | /bin/bash -c ' \
64 | set -x && \
65 | [[ -d /bash-$(1) ]] && \
66 | export PATH=/bash-$(1)/bin:$$PATH && \
67 | bash --version && \
68 | make test \
69 | '
70 | endef
71 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/Meta:
--------------------------------------------------------------------------------
1 | =meta: 0.0.2
2 |
3 | name: bashplus
4 | version: 0.0.9
5 | abstract: Modern Bash Programming
6 | homepage: http://bpan.org/package/bashplus/
7 |
8 | license: MIT
9 | copyright: 2013-2020
10 | author:
11 | name: Ingy döt Net
12 | email: ingy@ingy.net
13 | github: ingydotnet
14 | twitter: ingydotnet
15 | freenode: ingy
16 | homepage: http://ingy.net
17 |
18 | requires:
19 | bash: 4.4.0
20 | test:
21 | cmd: make test
22 | install:
23 | cmd: make install
24 |
25 | devel:
26 | git: git@github.org/ingydotnet/bashplus
27 | irc: irc.freenode.net/bpan
28 | bug: https://github.com/ingydotnet/bashplus/issues/
29 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/ReadMe.pod:
--------------------------------------------------------------------------------
1 | =pod
2 |
3 | =for comment
4 | DO NOT EDIT. This Pod was generated by Swim v0.1.48.
5 | See http://github.com/ingydotnet/swim-pm#readme
6 |
7 | =encoding utf8
8 |
9 | =head1 Name
10 |
11 | Bash+(1) - Modern Bash Programming
12 |
13 | =for html
14 |
15 |
16 | =head1 Synopsis
17 |
18 | source bash+ :std :array
19 |
20 | use Foo::Bar this that
21 |
22 | Array.new args "$@"
23 |
24 | if args.empty?; then
25 | die "I need args!"
26 | fi
27 |
28 | Foo::Bar.new foo args
29 |
30 | this is awesome # <= this is a real command! (You just imported it)
31 |
32 | =head1 Description
33 |
34 | Bash+ is just Bash... B some libraries that can make Bash programming a
35 | lot nicer.
36 |
37 | =for comment # Installation
38 |
39 | Get the source code from GitHub:
40 |
41 | git clone git@github.com:ingydotnet/bashplus
42 |
43 | Then run:
44 |
45 | make test
46 | make install # Possibly with 'sudo'
47 |
48 | =head1 Usage
49 |
50 | For now look at some libraries the use Bash+:
51 |
52 | =over
53 |
54 | =item * L
55 |
56 | =item * L
57 |
58 | =item * L
59 |
60 | =back
61 |
62 | =head1 Status
63 |
64 | If you are interested in chatting about this, C on
65 | irc.freenode.net.
66 |
67 | =head1 Author
68 |
69 | Written by Ingy döt Net
70 |
71 | =head1 Copyright & License
72 |
73 | Copyright 2013-2020. Ingy döt Net.
74 |
75 | The MIT License (MIT).
76 |
77 | =cut
78 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/bin/bash+:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #------------------------------------------------------------------------------
3 | # Bash+ - Modern Bash Programming
4 | #
5 | # Copyright (c) 2013-2020 Ingy döt Net
6 | #------------------------------------------------------------------------------
7 |
8 | set -e
9 | shopt -s compat31 &>/dev/null || true
10 |
11 | #------------------------------------------------------------------------------
12 | # Determine how `bash+` was called, and do the right thing:
13 | #------------------------------------------------------------------------------
14 | if [[ ${BASH_SOURCE[0]} != "$0" ]]; then
15 | # 'bash+' is being sourced:
16 | [[ ${BASH_SOURCE[0]} =~ /bin/bash\\+$ ]] || {
17 | echo "Invalid Bash+ path '${BASH_SOURCE[0]}'" 2> /dev/null
18 | exit 1
19 | }
20 | source "${BASH_SOURCE[0]%/bin/*}"/lib/bash+.bash || return $?
21 | bash+:import "$@"
22 | return $?
23 |
24 | else
25 | if [[ $# -eq 1 ]] && [[ $1 == --version ]]; then
26 | echo 'bash+ version 0.0.9'
27 | else
28 | cat <<'...'
29 |
30 | Greetings modern Bash programmer. Welcome to Bash+!
31 |
32 | Bash+ is framework that makes Bash programming more like Ruby and Perl.
33 |
34 | See: https://github.com/bpan-org/bashplus
35 |
36 | If you got here trying to use bash+ in a program, you need to source it:
37 |
38 | source bash+
39 |
40 | Happy Bash Hacking!
41 |
42 | ...
43 | fi
44 | fi
45 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/doc/bash+.swim:
--------------------------------------------------------------------------------
1 | Bash+(1)
2 | ========
3 |
4 | Modern Bash Programming
5 |
6 |
7 |
8 | = Synopsis
9 |
10 | source bash+ :std :array
11 |
12 | use Foo::Bar this that
13 |
14 | Array.new args "$@"
15 |
16 | if args.empty?; then
17 | die "I need args!"
18 | fi
19 |
20 | Foo::Bar.new foo args
21 |
22 | this is awesome # <= this is a real command! (You just imported it)
23 |
24 | = Description
25 |
26 | Bash+ is just Bash... *plus* some libraries that can make Bash programming a
27 | lot nicer.
28 |
29 | ## Installation
30 |
31 | Get the source code from GitHub:
32 |
33 | git clone git@github.com:ingydotnet/bashplus
34 |
35 | Then run:
36 |
37 | make test
38 | make install # Possibly with 'sudo'
39 |
40 | = Usage
41 |
42 | For now look at some libraries the use Bash+:
43 |
44 | * https://github.com/ingydotnet/git-hub
45 | * https://github.com/ingydotnet/json-bash
46 | * https://github.com/ingydotnet/test-more-bash
47 |
48 | = Status
49 |
50 | If you are interested in chatting about this, `/join #bpan` on
51 | irc.freenode.net.
52 |
53 | = Author
54 |
55 | Written by Ingy döt Net
56 |
57 | = Copyright & License
58 |
59 | Copyright 2013-2020. Ingy döt Net.
60 |
61 | The MIT License (MIT).
62 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/lib/bash+.bash:
--------------------------------------------------------------------------------
1 | # bash+ - Modern Bash Programming
2 | #
3 | # Copyright (c) 2013-2020 Ingy döt Net
4 |
5 | set -e
6 |
7 | [[ ${BASHPLUS_VERSION-} ]] && return 0
8 |
9 | BASHPLUS_VERSION=0.0.9
10 |
11 | bash+:version-check() {
12 | local cmd want got out
13 |
14 | IFS=' ' read -r -a cmd <<< "${1:?}"
15 | IFS=. read -r -a want <<< "${2:?}"
16 | : "${want[2]:=0}"
17 |
18 | if [[ ${cmd[*]} == bash ]]; then
19 | got=("${BASH_VERSINFO[@]}")
20 | BASHPLUS_VERSION_CHECK=${BASH_VERSION-}
21 | else
22 | [[ ${#cmd[*]} -gt 1 ]] || cmd+=(--version)
23 | out=$("${cmd[@]}") ||
24 | { echo "Failed to run '${cmd[*]}'" >&2; exit 1; }
25 | [[ $out =~ ([0-9]+\.[0-9]+(\.[0-9]+)?) ]] ||
26 | { echo "Can't determine version number from '${cmd[*]}'" >&2; exit 1; }
27 | BASHPLUS_VERSION_CHECK=${BASH_REMATCH[1]}
28 | IFS=. read -r -a got <<< "$BASHPLUS_VERSION_CHECK"
29 | fi
30 | : "${got[2]:=0}"
31 |
32 | ((
33 | got[0] > want[0] ||
34 | got[0] == want[0] && got[1] > want[1] ||
35 | got[0] == want[0] && got[1] == want[1] && got[2] >= want[2]
36 | )) || return 1
37 |
38 | return 0
39 | }
40 |
41 | bash+:version-check bash 3.2 ||
42 | { echo "The 'bashplus' library requires 'Bash 3.2+'." >&2; exit 1; }
43 |
44 | @() (echo "$@") # XXX do we want to keep this?
45 |
46 | bash+:export:std() {
47 | set -o pipefail
48 |
49 | if bash+:version-check bash 4.4; then
50 | set -o nounset
51 | shopt -s inherit_errexit
52 | fi
53 |
54 | echo use die warn
55 | }
56 |
57 | # Source a bash library call import on it:
58 | bash+:use() {
59 | local library_name=${1:?bash+:use requires library name}; shift
60 | local library_path=; library_path=$(bash+:findlib "$library_name") || true
61 | [[ $library_path ]] ||
62 | bash+:die "Can't find library '$library_name'." 1
63 |
64 | source "$library_path"
65 | if bash+:can "$library_name:import"; then
66 | "$library_name:import" "$@"
67 | else
68 | bash+:import "$@"
69 | fi
70 | }
71 |
72 | # Copy bash+: functions to unprefixed functions
73 | bash+:import() {
74 | local arg=
75 | for arg; do
76 | if [[ $arg =~ ^: ]]; then
77 | # Word splitting required here
78 | # shellcheck disable=2046
79 | bash+:import $(bash+:export"$arg")
80 | else
81 | bash+:fcopy "bash+:$arg" "$arg"
82 | fi
83 | done
84 | }
85 |
86 | # Function copy
87 | bash+:fcopy() {
88 | bash+:can "${1:?bash+:fcopy requires an input function name}" ||
89 | bash+:die "'$1' is not a function" 2
90 | local func
91 | func=$(type "$1" 3>/dev/null | tail -n+3)
92 | [[ ${3-} ]] && "$3"
93 | eval "${2:?bash+:fcopy requires an output function name}() $func"
94 | }
95 |
96 | # Find the path of a library
97 | bash+:findlib() {
98 | local library_name
99 | library_name=$(tr '[:upper:]' '[:lower:]' <<< "${1//:://}").bash
100 | local lib=${BASHPLUSLIB:-${BASHLIB:-$PATH}}
101 | library_name=${library_name//+/\\+}
102 | IFS=':' read -r -a libs <<< "$lib"
103 | find "${libs[@]}" -name "${library_name##*/}" 2>/dev/null |
104 | grep -E "$library_name\$" |
105 | head -n1
106 | }
107 |
108 | bash+:die() {
109 | local msg=${1:-Died}
110 | msg=${msg//\\n/$'\n'}
111 |
112 | printf "%s" "$msg" >&2
113 | if [[ $msg == *$'\n' ]]; then
114 | exit 1
115 | else
116 | printf "\n"
117 | fi
118 |
119 | local c
120 | IFS=' ' read -r -a c <<< "$(caller "${DIE_STACK_LEVEL:-${2:-0}}")"
121 | if (( ${#c[@]} == 2 )); then
122 | msg=" at line %d of %s"
123 | else
124 | msg=" at line %d in %s of %s"
125 | fi
126 |
127 | # shellcheck disable=2059
128 | printf "$msg\n" "${c[@]}" >&2
129 | exit 1
130 | }
131 |
132 | bash+:warn() {
133 | local msg=${1:-Warning}
134 | printf "%s" "${msg//\\n/$'\n'}\n" >&2
135 | }
136 |
137 | bash+:can() {
138 | [[ $(type -t "${1:?bash+:can requires a function name}") == function ]]
139 | }
140 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/man/man1/bash+.1:
--------------------------------------------------------------------------------
1 | .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
2 | .\"
3 | .\" Standard preamble:
4 | .\" ========================================================================
5 | .de Sp \" Vertical space (when we can't use .PP)
6 | .if t .sp .5v
7 | .if n .sp
8 | ..
9 | .de Vb \" Begin verbatim text
10 | .ft CW
11 | .nf
12 | .ne \\$1
13 | ..
14 | .de Ve \" End verbatim text
15 | .ft R
16 | .fi
17 | ..
18 | .\" Set up some character translations and predefined strings. \*(-- will
19 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 | .\" nothing in troff, for use with C<>.
24 | .tr \(*W-
25 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 | .ie n \{\
27 | . ds -- \(*W-
28 | . ds PI pi
29 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 | . ds L" ""
32 | . ds R" ""
33 | . ds C` ""
34 | . ds C' ""
35 | 'br\}
36 | .el\{\
37 | . ds -- \|\(em\|
38 | . ds PI \(*p
39 | . ds L" ``
40 | . ds R" ''
41 | . ds C`
42 | . ds C'
43 | 'br\}
44 | .\"
45 | .\" Escape single quotes in literal strings from groff's Unicode transform.
46 | .ie \n(.g .ds Aq \(aq
47 | .el .ds Aq '
48 | .\"
49 | .\" If the F register is >0, we'll generate index entries on stderr for
50 | .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 | .\" entries marked with X<> in POD. Of course, you'll have to process the
52 | .\" output yourself in some meaningful fashion.
53 | .\"
54 | .\" Avoid warning from groff about undefined register 'F'.
55 | .de IX
56 | ..
57 | .nr rF 0
58 | .if \n(.g .if rF .nr rF 1
59 | .if (\n(rF:(\n(.g==0)) \{\
60 | . if \nF \{\
61 | . de IX
62 | . tm Index:\\$1\t\\n%\t"\\$2"
63 | ..
64 | . if !\nF==2 \{\
65 | . nr % 0
66 | . nr F 2
67 | . \}
68 | . \}
69 | .\}
70 | .rr rF
71 | .\" ========================================================================
72 | .\"
73 | .IX Title "STDIN 1"
74 | .TH STDIN 1 "November 2020" "Generated by Swim v0.1.48" "Modern Bash Programming"
75 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
76 | .\" way too many mistakes in technical documents.
77 | .if n .ad l
78 | .nh
79 | .SH "Name"
80 | .IX Header "Name"
81 | Bash+(1) \- Modern Bash Programming
82 | .SH "Synopsis"
83 | .IX Header "Synopsis"
84 | .Vb 1
85 | \& source bash+ :std :array
86 | \&
87 | \& use Foo::Bar this that
88 | \&
89 | \& Array.new args "$@"
90 | \&
91 | \& if args.empty?; then
92 | \& die "I need args!"
93 | \& fi
94 | \&
95 | \& Foo::Bar.new foo args
96 | \&
97 | \& this is awesome # <= this is a real command! (You just imported it)
98 | .Ve
99 | .SH "Description"
100 | .IX Header "Description"
101 | Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
102 | .PP
103 | Get the source code from GitHub:
104 | .PP
105 | .Vb 1
106 | \& git clone git@github.com:ingydotnet/bashplus
107 | .Ve
108 | .PP
109 | Then run:
110 | .PP
111 | .Vb 2
112 | \& make test
113 | \& make install # Possibly with \*(Aqsudo\*(Aq
114 | .Ve
115 | .SH "Usage"
116 | .IX Header "Usage"
117 | For now look at some libraries the use Bash+:
118 | .IP "\(bu" 4
119 |
120 | .IP "\(bu" 4
121 |
122 | .IP "\(bu" 4
123 |
124 | .SH "Status"
125 | .IX Header "Status"
126 | If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
127 | .SH "Author"
128 | .IX Header "Author"
129 | Written by Ingy döt Net
130 | .SH "Copyright & License"
131 | .IX Header "Copyright & License"
132 | Copyright 2013\-2020. Ingy döt Net.
133 | .PP
134 | The \s-1MIT\s0 License (\s-1MIT\s0).
135 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/man/man3/bash+.3:
--------------------------------------------------------------------------------
1 | .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
2 | .\"
3 | .\" Standard preamble:
4 | .\" ========================================================================
5 | .de Sp \" Vertical space (when we can't use .PP)
6 | .if t .sp .5v
7 | .if n .sp
8 | ..
9 | .de Vb \" Begin verbatim text
10 | .ft CW
11 | .nf
12 | .ne \\$1
13 | ..
14 | .de Ve \" End verbatim text
15 | .ft R
16 | .fi
17 | ..
18 | .\" Set up some character translations and predefined strings. \*(-- will
19 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 | .\" nothing in troff, for use with C<>.
24 | .tr \(*W-
25 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 | .ie n \{\
27 | . ds -- \(*W-
28 | . ds PI pi
29 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 | . ds L" ""
32 | . ds R" ""
33 | . ds C` ""
34 | . ds C' ""
35 | 'br\}
36 | .el\{\
37 | . ds -- \|\(em\|
38 | . ds PI \(*p
39 | . ds L" ``
40 | . ds R" ''
41 | . ds C`
42 | . ds C'
43 | 'br\}
44 | .\"
45 | .\" Escape single quotes in literal strings from groff's Unicode transform.
46 | .ie \n(.g .ds Aq \(aq
47 | .el .ds Aq '
48 | .\"
49 | .\" If the F register is >0, we'll generate index entries on stderr for
50 | .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 | .\" entries marked with X<> in POD. Of course, you'll have to process the
52 | .\" output yourself in some meaningful fashion.
53 | .\"
54 | .\" Avoid warning from groff about undefined register 'F'.
55 | .de IX
56 | ..
57 | .nr rF 0
58 | .if \n(.g .if rF .nr rF 1
59 | .if (\n(rF:(\n(.g==0)) \{\
60 | . if \nF \{\
61 | . de IX
62 | . tm Index:\\$1\t\\n%\t"\\$2"
63 | ..
64 | . if !\nF==2 \{\
65 | . nr % 0
66 | . nr F 2
67 | . \}
68 | . \}
69 | .\}
70 | .rr rF
71 | .\" ========================================================================
72 | .\"
73 | .IX Title "STDIN 1"
74 | .TH STDIN 1 "November 2020" "Generated by Swim v0.1.48" "Modern Bash Programming"
75 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
76 | .\" way too many mistakes in technical documents.
77 | .if n .ad l
78 | .nh
79 | .SH "Name"
80 | .IX Header "Name"
81 | Bash+(1) \- Modern Bash Programming
82 | .SH "Synopsis"
83 | .IX Header "Synopsis"
84 | .Vb 1
85 | \& source bash+ :std :array
86 | \&
87 | \& use Foo::Bar this that
88 | \&
89 | \& Array.new args "$@"
90 | \&
91 | \& if args.empty?; then
92 | \& die "I need args!"
93 | \& fi
94 | \&
95 | \& Foo::Bar.new foo args
96 | \&
97 | \& this is awesome # <= this is a real command! (You just imported it)
98 | .Ve
99 | .SH "Description"
100 | .IX Header "Description"
101 | Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
102 | .PP
103 | Get the source code from GitHub:
104 | .PP
105 | .Vb 1
106 | \& git clone git@github.com:ingydotnet/bashplus
107 | .Ve
108 | .PP
109 | Then run:
110 | .PP
111 | .Vb 2
112 | \& make test
113 | \& make install # Possibly with \*(Aqsudo\*(Aq
114 | .Ve
115 | .SH "Usage"
116 | .IX Header "Usage"
117 | For now look at some libraries the use Bash+:
118 | .IP "\(bu" 4
119 |
120 | .IP "\(bu" 4
121 |
122 | .IP "\(bu" 4
123 |
124 | .SH "Status"
125 | .IX Header "Status"
126 | If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
127 | .SH "Author"
128 | .IX Header "Author"
129 | Written by Ingy döt Net
130 | .SH "Copyright & License"
131 | .IX Header "Copyright & License"
132 | Copyright 2013\-2020. Ingy döt Net.
133 | .PP
134 | The \s-1MIT\s0 License (\s-1MIT\s0).
135 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/base.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+ :std
7 |
8 | ok $? "'source bash+' works"
9 |
10 | is "$BASHPLUS_VERSION" '0.0.9' 'BASHPLUS_VERSION is 0.0.9'
11 |
12 | done_testing 2
13 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/die.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+ :std
7 |
8 | got=$(die "Nope" 2>&1) || true
9 | want="Nope
10 | at line 8 in main of test/die.t"
11 | is "$got" "$want" "die() msg ok"
12 |
13 | got=$(die "Nope\n" 2>&1) || true
14 | want="Nope"
15 | is "$got" "$want" "die() msg ok"
16 |
17 | done_testing 2
18 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/fcopy.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+
7 |
8 | foo() {
9 | echo O HAI
10 | }
11 |
12 | like "$(type bar 2>&1)" 'bar: not found' \
13 | 'bar is not yet a function'
14 |
15 | bash+:fcopy foo bar
16 |
17 | type -t bar &>/dev/null
18 | ok $? 'bar is now a function'
19 | is "$(type foo | tail -n+3)" "$(type bar | tail -n+3)" \
20 | 'Copy matches original'
21 |
22 | done_testing 3
23 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/lib/foo/bar.bash:
--------------------------------------------------------------------------------
1 | Foo__Bar_VERSION='1.2.3'
2 |
3 | Foo::Bar:baz() { :;}
4 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/lib/foo/foo.bash:
--------------------------------------------------------------------------------
1 | Foo::Foo:import() {
2 | echo $1---$2
3 | }
4 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/setup:
--------------------------------------------------------------------------------
1 | # shellcheck shell=bash
2 |
3 | #------------------------------------------------------------------------------
4 | # This is a tiny version of test-more-bash that I use here. test-more-bash uses
5 | # bash+, so I want to avoid the circular dependency. This little guy does
6 | # 80-90% what test-more-bash does, with minimal code. It's a good example of
7 | # how nice Bash can be.
8 | #------------------------------------------------------------------------------
9 |
10 | set -e -u -o pipefail
11 | [[ $BASH_VERSION == 4.0* ]] && set +u
12 |
13 | run=0
14 |
15 | plan() {
16 | echo "1..$1"
17 | }
18 |
19 | pass() {
20 | (( ++run ))
21 | echo "ok $run${1:+ - $1}"
22 | }
23 |
24 | fail() {
25 | (( ++run ))
26 | echo "not ok $run${1:+ - $1}"
27 | }
28 |
29 | is() {
30 | if [[ $1 == "$2" ]]; then
31 | pass "$3"
32 | else
33 | fail "$3"
34 | diag "Got: $1"
35 | diag "Want: $2"
36 | fi
37 | }
38 |
39 | ok() {
40 | if (exit "${1:-$?}"); then
41 | pass "$2"
42 | else
43 | fail "$2"
44 | fi
45 | }
46 |
47 | like() {
48 | if [[ $1 =~ $2 ]]; then
49 | pass "$3"
50 | else
51 | fail "$3"
52 | diag "Got: $1"
53 | diag "Like: $2"
54 | fi
55 | }
56 |
57 | unlike() {
58 | if [[ ! $1 =~ $2 ]]; then
59 | pass "$3"
60 | else
61 | fail "$3"
62 | diag "Got: $1"
63 | diag "Dont: $2"
64 | fi
65 | }
66 |
67 | done_testing() {
68 | echo "1..${1:-$run}"
69 | }
70 |
71 | diag() {
72 | echo "# ${1//$'\n'/$'\n'# }" >&2
73 | }
74 |
75 | note() {
76 | echo "# ${1//$'\n'/$'\n'# }"
77 | }
78 |
79 | #! vim: ft=sh sw=2:
80 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/shellcheck.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+
7 |
8 | if ! command -v shellcheck >/dev/null; then
9 | plan skip_all "The 'shellcheck' utility is not installed"
10 | fi
11 | if [[ ! $(shellcheck --version) =~ 0\.7\.1 ]]; then
12 | plan skip_all "This test wants shellcheck version 0.7.1"
13 | fi
14 |
15 | IFS=$'\n' read -d '' -r -a shell_files <<< "$(
16 | find bin -type f
17 | find lib -type f
18 | echo test/setup
19 | find test -name '*.t'
20 | )" || true
21 |
22 | skips=(
23 | # We want to keep these 2 here always:
24 | SC1090 # Can't follow non-constant source. Use a directive to specify location.
25 | SC1091 # Not following: bash+ was not specified as input (see shellcheck -x).
26 | )
27 |
28 | skip=$(IFS=,; echo "${skips[*]}")
29 |
30 | for file in "${shell_files[@]}"; do
31 | [[ $file == *swp ]] && continue
32 | is "$(shellcheck -e "$skip" "$file")" "" \
33 | "The shell file '$file' passes shellcheck"
34 | done
35 |
36 | done_testing
37 |
38 | # vim: set ft=sh:
39 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/source-bash+-std.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+ :std
7 |
8 | ok "$(bash+:can use)" 'use is imported'
9 | ok "$(bash+:can die)" 'die is imported'
10 | ok "$(bash+:can warn)" 'warn is imported'
11 |
12 | ok "$(! bash+:can import)" 'import is not imported'
13 | ok "$(! bash+:can main)" 'main is not imported'
14 | ok "$(! bash+:can fcopy)" 'fcopy is not imported'
15 | ok "$(! bash+:can findlib)" 'findlib is not imported'
16 | ok "$(! bash+:can can)" 'can is not imported'
17 |
18 | done_testing 8
19 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/source-bash+.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+
7 |
8 | functions=(
9 | use
10 | import
11 | fcopy
12 | findlib
13 | die
14 | warn
15 | can
16 | )
17 |
18 | for f in "${functions[@]}"; do
19 | is "$(type -t "bash+:$f")" function \
20 | "bash+:$f is a function"
21 | done
22 |
23 | done_testing 7
24 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/bashplus/test/use.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | PATH=$PWD/bin:$PATH
6 | source bash+ :std can
7 |
8 | # shellcheck disable=2034
9 | BASHLIB=test/lib
10 |
11 | use Foo::Bar
12 |
13 | ok $? 'use Foo::Bar - works'
14 | ok "$(can Foo::Bar:baz)" 'Function Foo::Bar:baz exists'
15 |
16 | # shellcheck disable=2016,2154
17 | is "$Foo__Bar_VERSION" 1.2.3 '$Foo__Bar_VERSION == 1.2.3'
18 |
19 | output=$(use Foo::Foo Boo Booo)
20 | ok $? 'use Foo::Foo Boo Booo - works'
21 | is "$output" Boo---Booo 'Correct import called'
22 |
23 | done_testing 5
24 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/.gitrepo:
--------------------------------------------------------------------------------
1 | ; DO NOT EDIT (unless you know what you are doing)
2 | ;
3 | ; This subdirectory is a git "subrepo", and this file is maintained by the
4 | ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5 | ;
6 | [subrepo]
7 | remote = git@github.com:ingydotnet/test-tap-bash.git
8 | branch = master
9 | commit = a9b33446848440a445f664a942f676d726788eff
10 | parent = 24ba0cb0c97d2591cfc2c106a70b1d1f8c559e01
11 | cmdver = 0.4.1
12 | method = merge
13 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/.travis.yml:
--------------------------------------------------------------------------------
1 | # C language gives closest shell env.
2 | language: c
3 |
4 | script:
5 | - make test PROVEOPT=-v
6 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/Changes:
--------------------------------------------------------------------------------
1 | ---
2 | version: 0.0.6
3 | date: Tue 03 Nov 2020 05:20:54 PM EST
4 | changes:
5 | - Workaround for bash 4.0 bug
6 | - Docker testing for all bash versions
7 | ---
8 | version: 0.0.5
9 | date: Tue 03 Nov 2020 01:15:41 PM EST
10 | changes:
11 | - Use more modern Bash idioms
12 | ---
13 | version: 0.0.4
14 | date: Sat Jan 23 16:32:22 PST 2016
15 | changes:
16 | - Make up to date.
17 | ---
18 | version: 0.0.3
19 | date: Fri Jan 23 21:39:39 PST 2015
20 | changes:
21 | - Make up to date.
22 | ---
23 | version: 0.0.1
24 | date: Sun Oct 27 23:02:11 PDT 2013
25 | changes:
26 | - First release.
27 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/License:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright © 2013-2020. Ingy döt Net.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the ‘Software’), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/Makefile:
--------------------------------------------------------------------------------
1 | SHELL := bash
2 |
3 | ifeq ($(MAKECMDGOALS),install)
4 | ifeq "$(shell bpan version 2>/dev/null)" ""
5 | $(error 'BPAN not installed. See http://bpan.org')
6 | endif
7 | endif
8 |
9 | NAME := test-tap
10 | LIB := lib/test/tap.bash
11 | MAN3 := man/man3
12 |
13 | INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
14 | INSTALL_DIR ?= test
15 | INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
16 |
17 | DOCKER_IMAGE := ingy/bash-testing:0.0.1
18 |
19 | default: help
20 |
21 | help:
22 | @echo 'Rules: test, install, doc'
23 |
24 | .PHONY: test
25 | test:
26 | prove $(PROVEOPT:%=% )test/
27 |
28 | test-all: test docker-test
29 |
30 | docker-test:
31 | -$(call docker-make-test,3.2)
32 | -$(call docker-make-test,4.0)
33 | -$(call docker-make-test,4.1)
34 | -$(call docker-make-test,4.2)
35 | -$(call docker-make-test,4.3)
36 | -$(call docker-make-test,4.4)
37 | -$(call docker-make-test,5.0)
38 | -$(call docker-make-test,5.1)
39 |
40 | install:
41 | install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
42 | install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
43 | install -C -d -m 0755 $(INSTALL_MAN3)/
44 | install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
45 |
46 | .PHONY: doc
47 | doc: ReadMe.pod $(MAN3)/$(NAME).3
48 |
49 | ReadMe.pod: doc/test-tap.swim
50 | swim --to=pod --complete --wrap $< > $@
51 |
52 | man/man3/%.3: doc/%.swim
53 | swim --to=man $< > $@
54 |
55 | define docker-make-test
56 | docker run -i -t --rm \
57 | -v $(PWD):/git-subrepo \
58 | -w /git-subrepo \
59 | $(DOCKER_IMAGE) \
60 | /bin/bash -c ' \
61 | set -x && \
62 | [[ -d /bash-$(1) ]] && \
63 | export PATH=/bash-$(1)/bin:$$PATH && \
64 | bash --version && \
65 | make test \
66 | '
67 | endef
68 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/Meta:
--------------------------------------------------------------------------------
1 | =meta: 0.0.2
2 |
3 | name: test-tap
4 | version: 0.0.6
5 | abstract: TAP Test Base for Bash
6 | homepage: http://bpan.org/package/test-tap/
7 |
8 | license: MIT
9 | copyright: 2013-2020
10 | author:
11 | name: Ingy döt Net
12 | email: ingy@ingy.net
13 | github: ingydotnet
14 | twitter: ingydotnet
15 | freenode: ingy
16 | homepage: http://ingy.net
17 |
18 | requires:
19 | bash: 3.2.57
20 | test:
21 | cmd: make test
22 | install:
23 | cmd: make install
24 |
25 | devel:
26 | git: git@github.org/ingydotnet/test-tap-bash.git
27 | irc: irc.freenode.net/bpan
28 | bug: https://github.com/ingydotnet/test-tap-bash/issues/
29 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/ReadMe.pod:
--------------------------------------------------------------------------------
1 | =pod
2 |
3 | =for comment
4 | DO NOT EDIT. This Pod was generated by Swim v0.1.48.
5 | See http://github.com/ingydotnet/swim-pm#readme
6 |
7 | =encoding utf8
8 |
9 | =head1 Name
10 |
11 | Test::Tap - TAP Test Base for Bash
12 |
13 | =for html
14 |
15 |
16 | =head1 Synopsis
17 |
18 | source test/tap.bash
19 |
20 | Test::Tap:plan tests 1
21 |
22 | pass 'Everything is OK!'
23 |
24 | =head1 Description
25 |
26 | This is a TAP testing base class for Bash. It has all the basic TAP functions,
27 | and works properly from a TAP harness, like the C utility.
28 |
29 | test-tap-bash is used as the base for test-more-bash, which is what you want
30 | if you are writing tests in bash.
31 |
32 | See: L
33 |
34 | =head1 Functions
35 |
36 | =over
37 |
38 | =item C
39 |
40 | Must be called first for every test file/process.
41 |
42 | =item C
43 |
44 | Used to set the plan.
45 |
46 | =back
47 |
48 | =head1 TODO
49 |
50 | =over
51 |
52 | =item * Finish this doc.
53 |
54 | =back
55 |
56 | =head1 Author
57 |
58 | Written by Ingy döt Net
59 |
60 | =head1 Copyright & License
61 |
62 | Copyright 2013-2020. Ingy döt Net.
63 |
64 | The MIT License (MIT).
65 |
66 | =cut
67 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/doc/test-tap.swim:
--------------------------------------------------------------------------------
1 | Test::Tap
2 | =========
3 |
4 | TAP Test Base for Bash
5 |
6 |
7 |
8 | = Synopsis
9 |
10 | source test/tap.bash
11 |
12 | Test::Tap:plan tests 1
13 |
14 | pass 'Everything is OK!'
15 |
16 | = Description
17 |
18 | This is a TAP testing base class for Bash. It has all the basic TAP functions,
19 | and works properly from a TAP harness, like the `prove` utility.
20 |
21 | test-tap-bash is used as the base for test-more-bash, which is what you want
22 | if you are writing tests in bash.
23 |
24 | See: https://github.com/ingydotnet/test-more-bash/
25 |
26 | = Functions
27 |
28 | - `Test::Tap:init`
29 |
30 | Must be called first for every test file/process.
31 |
32 | - `Test::Tap::plan`
33 |
34 | Used to set the plan.
35 |
36 | = TODO
37 |
38 | * Finish this doc.
39 |
40 | = Author
41 |
42 | Written by Ingy döt Net
43 |
44 | = Copyright & License
45 |
46 | Copyright 2013-2020. Ingy döt Net.
47 |
48 | The MIT License (MIT).
49 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/man/man3/test-tap.3:
--------------------------------------------------------------------------------
1 | .\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
2 | .\"
3 | .\" Standard preamble:
4 | .\" ========================================================================
5 | .de Sp \" Vertical space (when we can't use .PP)
6 | .if t .sp .5v
7 | .if n .sp
8 | ..
9 | .de Vb \" Begin verbatim text
10 | .ft CW
11 | .nf
12 | .ne \\$1
13 | ..
14 | .de Ve \" End verbatim text
15 | .ft R
16 | .fi
17 | ..
18 | .\" Set up some character translations and predefined strings. \*(-- will
19 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 | .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 | .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 | .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 | .\" nothing in troff, for use with C<>.
24 | .tr \(*W-
25 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 | .ie n \{\
27 | . ds -- \(*W-
28 | . ds PI pi
29 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 | . ds L" ""
32 | . ds R" ""
33 | . ds C` ""
34 | . ds C' ""
35 | 'br\}
36 | .el\{\
37 | . ds -- \|\(em\|
38 | . ds PI \(*p
39 | . ds L" ``
40 | . ds R" ''
41 | . ds C`
42 | . ds C'
43 | 'br\}
44 | .\"
45 | .\" Escape single quotes in literal strings from groff's Unicode transform.
46 | .ie \n(.g .ds Aq \(aq
47 | .el .ds Aq '
48 | .\"
49 | .\" If the F register is >0, we'll generate index entries on stderr for
50 | .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
51 | .\" entries marked with X<> in POD. Of course, you'll have to process the
52 | .\" output yourself in some meaningful fashion.
53 | .\"
54 | .\" Avoid warning from groff about undefined register 'F'.
55 | .de IX
56 | ..
57 | .nr rF 0
58 | .if \n(.g .if rF .nr rF 1
59 | .if (\n(rF:(\n(.g==0)) \{\
60 | . if \nF \{\
61 | . de IX
62 | . tm Index:\\$1\t\\n%\t"\\$2"
63 | ..
64 | . if !\nF==2 \{\
65 | . nr % 0
66 | . nr F 2
67 | . \}
68 | . \}
69 | .\}
70 | .rr rF
71 | .\" ========================================================================
72 | .\"
73 | .IX Title "STDIN 1"
74 | .TH STDIN 1 "November 2020" "Generated by Swim v0.1.48" "\s-1TAP\s0 Test Base for Bash"
75 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
76 | .\" way too many mistakes in technical documents.
77 | .if n .ad l
78 | .nh
79 | .SH "Name"
80 | .IX Header "Name"
81 | Test::Tap \- \s-1TAP\s0 Test Base for Bash
82 | .SH "Synopsis"
83 | .IX Header "Synopsis"
84 | .Vb 1
85 | \& source test/tap.bash
86 | \&
87 | \& Test::Tap:plan tests 1
88 | \&
89 | \& pass \*(AqEverything is OK!\*(Aq
90 | .Ve
91 | .SH "Description"
92 | .IX Header "Description"
93 | This is a \s-1TAP\s0 testing base class for Bash. It has all the basic \s-1TAP\s0 functions, and works properly from a \s-1TAP\s0 harness, like the \f(CW\*(C`prove\*(C'\fR utility.
94 | .PP
95 | test-tap-bash is used as the base for test-more-bash, which is what you want if you are writing tests in bash.
96 | .PP
97 | See:
98 | .SH "Functions"
99 | .IX Header "Functions"
100 | .ie n .IP """Test::Tap:init""" 4
101 | .el .IP "\f(CWTest::Tap:init\fR" 4
102 | .IX Item "Test::Tap:init"
103 | Must be called first for every test file/process.
104 | .ie n .IP """Test::Tap::plan""" 4
105 | .el .IP "\f(CWTest::Tap::plan\fR" 4
106 | .IX Item "Test::Tap::plan"
107 | Used to set the plan.
108 | .SH "TODO"
109 | .IX Header "TODO"
110 | .IP "\(bu" 4
111 | Finish this doc.
112 | .SH "Author"
113 | .IX Header "Author"
114 | Written by Ingy döt Net
115 | .SH "Copyright & License"
116 | .IX Header "Copyright & License"
117 | Copyright 2013\-2020. Ingy döt Net.
118 | .PP
119 | The \s-1MIT\s0 License (\s-1MIT\s0).
120 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/bail_out.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/helper.bash
4 | source lib/test/tap.bash
5 |
6 | Test::Tap:init tests 1
7 |
8 | output=$(prove -v test/test/{b,f}ail.t 2>&1) || true
9 |
10 | test-helper:like \
11 | "$output" \
12 | 'Bailout called. Further testing stopped: Get me outta here' \
13 | 'Test::Tap:BAIL_OUT works'
14 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/done.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init
6 |
7 | Test::Tap:pass one
8 | Test::Tap:pass two
9 |
10 | Test::Tap:done_testing
11 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/fail.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/helper.bash
4 | source lib/test/tap.bash
5 |
6 | Test::Tap:init tests 2
7 |
8 | output=$(prove -v test/test/fail.t 2>&1) || true
9 |
10 | # echo "# >>>${output//$'\n'/$'\n'# }<<<" >&2
11 |
12 | test-helper:like \
13 | "$output" \
14 | 'not ok 1 - I am a failure' \
15 | 'Test::Tap:fail works'
16 |
17 | test-helper:like \
18 | "$output" \
19 | 'Failed 1/1 subtests' \
20 | 'Proper summary'
21 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/fail_fast.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/helper.bash
4 | source lib/test/tap.bash
5 |
6 | Test::Tap:init tests 1
7 |
8 | output=$(prove -v test/test/fail_fast.t 2>&1) || true
9 |
10 | # echo ">>>$output<<<" >&2
11 |
12 | test-helper:like \
13 | "$output" \
14 | 'Further testing stopped: Bailing out on status=1' \
15 | 'Test::Tap:BAIL_OUT works'
16 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/helper.bash:
--------------------------------------------------------------------------------
1 | test-helper:like() {
2 | local got=$1 regex=$2 label=$3
3 | if [[ $got =~ $regex ]]; then
4 | Test::Tap:pass "$label"
5 | else
6 | Test::Tap:fail "$label"
7 | Test::Tap:diag "Got: '$got'"
8 | fi
9 | }
10 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/pass.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init tests 3
6 |
7 | Test::Tap:pass 'pass 1 - with label'
8 | Test::Tap:pass
9 | Test::Tap:pass 'pass 3 - 2 has no label'
10 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/plan.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init
6 | Test::Tap:plan tests 3
7 |
8 | for n in 1 2 3; do
9 | Test::Tap:pass "Test #$n"
10 | done
11 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/shellcheck.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | if ! command -v shellcheck >/dev/null; then
6 | Test::Tap:init skip_all "The 'shellcheck' utility is not installed"
7 | fi
8 | if [[ ! $(shellcheck --version) =~ 0\.7\.1 ]]; then
9 | Test::Tap:init skip_all "This test wants shellcheck version 0.7.1"
10 | fi
11 |
12 | Test::Tap:init
13 |
14 | IFS=$'\n' read -d '' -r -a shell_files <<< "$(
15 | find lib -type f
16 | echo test/helper.bash
17 | find test -name '*.t'
18 | )" || true
19 |
20 | skips=(
21 | # We want to keep these 2 here always:
22 | SC1090 # Can't follow non-constant source. Use a directive to specify location.
23 | SC1091 # Not following: bash+ was not specified as input (see shellcheck -x).
24 | )
25 |
26 | skip=$(IFS=,; echo "${skips[*]}")
27 |
28 | for file in "${shell_files[@]}"; do
29 | [[ $file == *swp ]] && continue
30 | label="The shell file '$file' passes shellcheck"
31 | got=$(shellcheck -e "$skip" "$file" 2>&1) || true
32 | if [[ -z $got ]]; then
33 | Test::Tap:pass "$label"
34 | else
35 | Test::Tap:fail "$label"
36 | Test::Tap:diag "$got"
37 | fi
38 | done
39 |
40 | Test::Tap:done_testing
41 |
42 | # vim: set ft=sh:
43 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/skip_all.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/helper.bash
4 | source lib/test/tap.bash
5 |
6 | Test::Tap:init tests 4
7 |
8 | for s in plan init; do
9 | output=$(prove test/test/skip-all-$s.t)
10 |
11 | test-helper:like \
12 | "$output" \
13 | "skipped: Test for skip_all from $s" \
14 | "skip_all from $s: it works"
15 |
16 | test-helper:like \
17 | "$output" \
18 | 'Result: NOTESTS' \
19 | "skip_all from $s: No tests run"
20 | done
21 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/tap.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init tests 3 # 4
6 |
7 | Test::Tap:pass 'pass with label'
8 | Test::Tap:pass
9 | Test::Tap:pass 'previous test has no label'
10 |
11 | # TODO this test no longer working:
12 | # msg=$(Test::Tap:fail 'faaaaailll' 2>/dev/null) || true
13 | #
14 | # if [[ $msg =~ not\ ok\ 4\ -\ faaaaailll ]]; then
15 | # Test::Tap:pass 'fail works'
16 | # else
17 | # Test::Tap:fail 'fail works'
18 | # Test::Tap:diag "$msg"
19 | # fi
20 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/test/bail.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init tests 5
6 |
7 | Test::Tap:pass 'test #1'
8 | Test::Tap:pass 'test #2'
9 | Test::Tap:pass 'test #3'
10 |
11 | Test::Tap:BAIL_OUT 'Get me outta here'
12 |
13 | Test::Tap:pass 'test #4'
14 | Test::Tap:fail 'test #5'
15 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/test/fail.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init tests 1
6 |
7 | Test::Tap:fail 'I am a failure'
8 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/test/fail_fast.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init tests 5
6 | Test::Tap:BAIL_ON_FAIL
7 |
8 | Test::Tap:pass 'test #1'
9 | Test::Tap:pass 'test #2'
10 | Test::Tap:fail 'test #3'
11 | Test::Tap:pass 'test #4'
12 | Test::Tap:pass 'test #5'
13 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/test/skip-all-init.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init skip_all 'Test for skip_all from init'
6 |
7 | Test::Tap:diag "This code should not be run"
8 | Test::Tap:fail
9 |
--------------------------------------------------------------------------------
/ext/test-more-bash/ext/test-tap-bash/test/test/skip-all-plan.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source lib/test/tap.bash
4 |
5 | Test::Tap:init
6 | Test::Tap:plan skip_all 'Test for skip_all from plan'
7 |
8 | Test::Tap:diag "This code should not be run"
9 | Test::Tap:fail
10 |
--------------------------------------------------------------------------------
/ext/test-more-bash/lib/test/more.bash:
--------------------------------------------------------------------------------
1 | # test/more.bash - Complete TAP test framework for Bash
2 | #
3 | # Copyright (c) 2013-2020. Ingy döt Net.
4 |
5 | set -e -u -o pipefail
6 |
7 | # shellcheck disable=2034
8 | Test__More_VERSION=0.0.5
9 |
10 | source bash+ :std version-check
11 |
12 | version-check bash 3.2 ||
13 | die "test-more-bash requires bash 3.2+"
14 |
15 | use Test::Tap
16 |
17 | Test::More:import() { Test::Tap:init "$@"; }
18 |
19 | plan() { Test::Tap:plan "$@"; }
20 | pass() { Test::Tap:pass "$@"; }
21 | fail() { Test::Tap:fail "$@"; }
22 | diag() { Test::Tap:diag "$@"; }
23 | note() { Test::Tap:note "$@"; }
24 | done_testing() { Test::Tap:done_testing "$@"; }
25 | BAIL_OUT() { Test::Tap:BAIL_OUT "$@"; }
26 | BAIL_ON_FAIL() { Test::Tap:BAIL_ON_FAIL "$@"; }
27 |
28 | is() {
29 | local got=$1 want=$2 label=${3-}
30 | if [[ $got == "$want" ]]; then
31 | Test::Tap:pass "$label"
32 | else
33 | Test::Tap:fail "$label" Test::More:is-fail
34 | fi
35 | }
36 |
37 | Test::More:is-fail() {
38 | local Test__Tap_CALL_STACK_LEVEL=
39 | Test__Tap_CALL_STACK_LEVEL=$(( Test__Tap_CALL_STACK_LEVEL + 1 ))
40 | if [[ $want =~ $'\n' ]]; then
41 | echo "$got" > /tmp/got-$$
42 | echo "$want" > /tmp/want-$$
43 | diff -u /tmp/{want,got}-$$ >&2 || true
44 | wc /tmp/{want,got}-$$ >&2
45 | rm -f /tmp/{got,want}-$$
46 | else
47 | Test::Tap:diag "\
48 | got: '$got'
49 | expected: '$want'"
50 | fi
51 | }
52 |
53 | isnt() {
54 | local Test__Tap_CALL_STACK_LEVEL=
55 | Test__Tap_CALL_STACK_LEVEL=$(( Test__Tap_CALL_STACK_LEVEL + 1 ))
56 | local got=$1 dontwant=$2 label=${3-}
57 | if [[ $got != "$dontwant" ]]; then
58 | Test::Tap:pass "$label"
59 | else
60 | Test::Tap:fail "$label" Test::More:isnt-fail
61 | fi
62 | }
63 |
64 | Test::More:isnt-fail() {
65 | Test::Tap:diag "\
66 | got: '$got'
67 | expected: anything else"
68 | }
69 |
70 | ok() {
71 | if (exit "${1:-$?}"); then
72 | Test::Tap:pass "${2-}"
73 | else
74 | Test::Tap:fail "${2-}"
75 | fi
76 | }
77 |
78 | like() {
79 | local got=$1 regex=$2 label=${3-}
80 | if [[ $got =~ $regex ]]; then
81 | Test::Tap:pass "$label"
82 | else
83 | Test::Tap:fail "$label" Test::More:like-fail
84 | fi
85 | }
86 |
87 | Test::More:like-fail() {
88 | Test::Tap:diag "Got: '$got'"
89 | }
90 |
91 | unlike() {
92 | local got=$1 regex=$2 label=${3-}
93 | if [[ ! $got =~ $regex ]]; then
94 | Test::Tap:pass "$label"
95 | else
96 | Test::Tap:fail "$label" Test::More:unlike-fail
97 | fi
98 | }
99 |
100 | Test::More:unlike-fail() {
101 | Test::Tap:diag "Got: '$got'"
102 | }
103 |
104 | cmp-array() {
105 | local arrayname="$1[@]"
106 | local expname="$2[@]"
107 | local label=${3-}
108 |
109 | local array=("${!arrayname}")
110 | local expected=("${!expname}")
111 |
112 | is "$(printf "%s\n" "${array[@]}")" \
113 | "$(printf "%s\n" "${expected[@]}")" \
114 | "$label"
115 | }
116 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/fail.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | use Test::More
6 |
7 | output=$(prove -v test/test/fail1.t 2>&1) || true
8 |
9 | like "$output" 'not ok 1 - fail with label' \
10 | 'fail with label'
11 | like "$output" 'not ok 2' \
12 | 'fail with no label'
13 | like "$output" 'not ok 3 - is foo bar' \
14 | 'fail output is correct'
15 | like "$output" 'not ok 4 - command output more' \
16 | 'fail output is correct'
17 | like "$output" 'not ok 5 - command output less' \
18 | 'fail output is correct'
19 | like "$output" 'not ok 6 - command output diff' \
20 | 'fail output is correct'
21 | like "$output" "# got: 'foo'" \
22 | 'difference reporting - got'
23 | like "$output" "# expected: 'bar'" \
24 | 'difference reporting - want'
25 |
26 | like "$output" "line2. *\+line3." \
27 | 'array comparison (more)'
28 | like "$output" "line1. *-line2." \
29 | 'array comparison (less)'
30 | like "$output" "-line2.*\+foo" \
31 | 'array comparison (diff)'
32 |
33 |
34 | done_testing 11
35 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/more.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # shellcheck disable=2034
4 |
5 | source test/setup
6 | use Test::More
7 |
8 | plan tests 6
9 |
10 | pass 'This test always passes'
11 |
12 | is 'foo' "foo" 'foo is foo'
13 |
14 | ok "$(true)" 'true is true'
15 |
16 | ok "$([ 123 -eq "$((61+62))" ])" 'Math works'
17 |
18 | # shellcheck disable=2050
19 | ok "$([[ ! team =~ I ]])" "There's no I in team"
20 |
21 | # diag "A msg for stderr"
22 |
23 | note "A msg for stdout"
24 |
25 | expected=(line1 line2)
26 |
27 | command_output=(line1 line2 )
28 | cmp-array command_output expected "command output more"
29 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/pass.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 |
5 | use Test::More tests 3
6 |
7 | pass 'pass 1 - with label'
8 | pass
9 | pass 'pass 3 - 2 has no label'
10 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e -u -o pipefail
4 |
5 | BASHLIB=$(find "$PWD" -type d | grep -E '/(bin|lib)$' | xargs -n1 printf "%s:")
6 | PATH=$BASHLIB:$PATH
7 |
8 | source bash+ :std
9 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/shellcheck.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 | use Test::More
5 |
6 | if ! command -v shellcheck >/dev/null; then
7 | plan skip_all "The 'shellcheck' utility is not installed"
8 | fi
9 | if [[ ! $(shellcheck --version) =~ 0\.7\.1 ]]; then
10 | plan skip_all "This test wants shellcheck version 0.7.1"
11 | fi
12 |
13 | IFS=$'\n' read -d '' -r -a shell_files <<< "$(
14 | find lib -type f
15 | echo test/setup
16 | find test -name '*.t'
17 | )" || true
18 |
19 | skips=(
20 | # We want to keep these 2 here always:
21 | SC1090 # Can't follow non-constant source. Use a directive to specify location.
22 | SC1091 # Not following: bash+ was not specified as input (see shellcheck -x).
23 | )
24 |
25 | skip=$(IFS=,; echo "${skips[*]}")
26 |
27 | for file in "${shell_files[@]}"; do
28 | [[ $file == *swp ]] && continue
29 | is "$(shellcheck -e "$skip" "$file")" "" \
30 | "The shell file '$file' passes shellcheck"
31 | done
32 |
33 | done_testing
34 |
35 | # vim: set ft=sh:
36 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/skip_all.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 | use Test::More
5 |
6 | output=$(prove -v test/test/skip_all.t 2>&1) || true
7 |
8 | like "$output" 'skipped: Skipping this test to demo skip_all' \
9 | 'skip_all works'
10 |
11 | done_testing 1
12 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/test/fail1.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # shellcheck disable=2034
4 |
5 | source test/setup
6 | use Test::More
7 |
8 | fail 'fail with label'
9 |
10 | fail
11 |
12 | is foo bar 'is foo bar'
13 |
14 | expected=(line1 line2)
15 |
16 | command_output=(line1 line2 line3)
17 | cmp-array command_output expected "command output more"
18 |
19 | command_output=(line1)
20 | cmp-array command_output expected "command output less"
21 |
22 | command_output=(line1 foo)
23 | cmp-array command_output expected "command output diff"
24 |
25 | done_testing 6
26 |
--------------------------------------------------------------------------------
/ext/test-more-bash/test/test/skip_all.t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source test/setup
4 | use Test::More
5 |
6 | plan skip_all 'Skipping this test to demo skip_all'
7 |
8 | fail "Don't run this code"
9 |
10 | done_testing
11 |
--------------------------------------------------------------------------------
/lib/git-subrepo.d/bash+.bash:
--------------------------------------------------------------------------------
1 | ../../ext/bashplus/lib/bash+.bash
--------------------------------------------------------------------------------
/note/0.4.0:
--------------------------------------------------------------------------------
1 | - Update docs
2 | - Review issue/142
3 | - Compare operations to master
4 | - Add a --no-push or --dry-run flag for push
5 | - Add a --rebase option for push
6 | - Add --message= and --edit to the init command ??
7 | - Also add to doc
8 | - Update doc for steps of pull command to include merge and rebase
9 | - Test squashing on pull operations
10 | - Update push doc after understanding it more
11 | - Is --rebase for pull or push?
12 | - Make sure docs are correct too.
13 |
--------------------------------------------------------------------------------
/note/AllGitCmds:
--------------------------------------------------------------------------------
1 | add
2 | add--interactive
3 | am
4 | annotate
5 | apply
6 | archive
7 | bisect
8 | bisect--helper
9 | blame
10 | branch
11 | bundle
12 | cat-file
13 | check-attr
14 | check-ref-format
15 | checkout
16 | checkout-index
17 | cherry
18 | cherry-pick
19 | clean
20 | clone
21 | commit
22 | commit-tree
23 | config
24 | count-objects
25 | credential-cache
26 | credential-cache--daemon
27 | credential-store
28 | daemon
29 | describe
30 | diff
31 | diff-files
32 | diff-index
33 | diff-tree
34 | difftool
35 | difftool--helper
36 | fast-export
37 | fast-import
38 | fetch
39 | fetch-pack
40 | filter-branch
41 | fmt-merge-msg
42 | for-each-ref
43 | format-patch
44 | fsck
45 | fsck-objects
46 | gc
47 | get-tar-commit-id
48 | grep
49 | hash-object
50 | help
51 | http-backend
52 | http-fetch
53 | http-push
54 | hub
55 | imap-send
56 | index-pack
57 | init
58 | init-db
59 | instaweb
60 | log
61 | lost-found
62 | ls-files
63 | ls-remote
64 | ls-tree
65 | mailinfo
66 | mailsplit
67 | merge
68 | merge-base
69 | merge-file
70 | merge-index
71 | merge-octopus
72 | merge-one-file
73 | merge-ours
74 | merge-recursive
75 | merge-resolve
76 | merge-subtree
77 | merge-tree
78 | mergetool
79 | mktag
80 | mktree
81 | mv
82 | name-rev
83 | notes
84 | pack-objects
85 | pack-redundant
86 | pack-refs
87 | patch-id
88 | peek-remote
89 | prune
90 | prune-packed
91 | pull
92 | push
93 | quiltimport
94 | read-tree
95 | rebase
96 | receive-pack
97 | reflog
98 | relink
99 | remote
100 | remote-ext
101 | remote-fd
102 | remote-ftp
103 | remote-ftps
104 | remote-http
105 | remote-https
106 | remote-testgit
107 | remove-submodule
108 | repack
109 | replace
110 | repo-config
111 | request-pull
112 | rerere
113 | reset
114 | rev-list
115 | rev-parse
116 | revert
117 | rm
118 | send-pack
119 | sh-i18n--envsubst
120 | shell
121 | shortlog
122 | show
123 | show-branch
124 | show-index
125 | show-ref
126 | stage
127 | stash
128 | status
129 | stripspace
130 | submodule
131 | subrepo
132 | subtree
133 | symbolic-ref
134 | tag
135 | tar-tree
136 | unpack-file
137 | unpack-objects
138 | update-index
139 | update-ref
140 | update-server-info
141 | upload-archive
142 | upload-pack
143 | var
144 | verify-pack
145 | verify-tag
146 | web--browse
147 | whatchanged
148 | write-tree
149 |
--------------------------------------------------------------------------------
/note/Cases:
--------------------------------------------------------------------------------
1 | == Users
2 |
3 | - art — project lead
4 | - bob — end user
5 | - cab — collab dev (push rights)
6 | - dim — forker dev (no push rights)
7 | - ell — third party repo owner
8 |
9 | == Repos
10 | - art/gallery — art's main repo
11 | - art/painting — subrepo owned by art
12 | - ell/tickets — subrepo owned by ell
13 |
14 | == Starting histories:
15 | - art/gallery — A---B
16 | - art/painting — P---Q
17 | - ell/tickets — T
18 |
19 | == Scenario 1
20 | art art/gallery$ git log
21 | A---B
22 | art art/gallery$ git subrepo clone art/painting
23 | art art/gallery$ ls
24 | painting/
25 | art art/gallery$ git log
26 | A---B---C
27 | /
28 | Q'
29 | art art/gallery$
30 |
--------------------------------------------------------------------------------
/note/Commands:
--------------------------------------------------------------------------------
1 | $$$ for cmd in `cat AllGitCmds`; do git help $cmd; done
2 |
3 |
4 | == Inteesting Plumbing Commands:
5 | - git ls-tree HEAD
6 | - git cat-file -t