fixes after makefile crash

pull/10/head
sobolevn 8 years ago
commit b370149e18

BIN
.DS_Store vendored

Binary file not shown.

@ -0,0 +1,26 @@
# Check http://editorconfig.org for more information
# This is the main config file for this project:
root = true
[*]
charset = utf-8
indent_style = space
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true
[*.json]
indent_size = 2
[*.py]
indent_size = 4
[*.sh]
indent_size = 2
[*.bats]
indent_size = 2
[Makefile]
indent_style = tab
indent_size = 4

1
.gitattributes vendored

@ -0,0 +1 @@
* text=auto

@ -0,0 +1,18 @@
language: c
sudo: false
branches:
only:
- master
install:
- make install-test
script:
- make test
notifications:
email:
on_success: never
on_failure: change

@ -0,0 +1,33 @@
all: build
git-secret: src/_utils/* src/commands/* src/main.sh
@cat $^ > "$@"
@chmod +x git-secret
clean:
@rm -f git-secret
build: git-secret
install-test:
git clone https://github.com/sstephenson/bats.git vendor/bats
test:
@if [ ! -d "vendor/bats" ]; then make install-test; fi
@export SECRET_PROJECT_ROOT="${PWD}"; export PATH="${PWD}/vendor/bats/bin:${PWD}:${PATH}"; \
make develop; \
rm -rf temp; mkdir temp; cd temp; \
bats "../tests";
install-man:
gem install ronn
build-man:
@if [ ! `gem list ronn -i` == "true" ]; then make install-man; fi
ronn --roff man/man1/*.ronn
install-hooks:
@ln -fs "${PWD}/utils/pre-commit.sh" "${PWD}/.git/hooks/pre-commit"
@chmod +x "${PWD}/.git/hooks/pre-commit"
develop: clean build install-hooks

@ -0,0 +1,44 @@
# git-secret
[![Build Status](https://secure.travis-ci.org/sobolevn/git-secret.png?branch=master)](https://travis-ci.org/sobolevn/git-secret)
## Status
This project is still under development. Current objectives:
- add '-h|-?' to all commands
- add `trust-model` parameter to `git-secret-hide`
- add exception when running `git secret hide` with no files added
- manuals
- hooks: `pre-commit` to encrypt secret files
- static site for `gh-pages` build from manuals with `Jekyll` and `Ronn`
- plugin for `zsh`
- extra tests
- precompiled distributions for `brew` and other package managers
- create CONTRIBUTING.md with custom styleguide and development-hooks: manual auto-build
- refactor code due to styleguide
- сygwin support (?)
## Requirements
`git-secret` works only with `git` and `gpg`, it is tested and works for Mac OS X, Ubuntu and Debian.
No other dependencies are required.
## Testing
For testing this project uses [`bats`](1). You can install it by running `make install-test`.
To run tests call: `make test`. It will download and install `bats` into `vandor/bats` if it's not installed yet.
## Installation
Right now installation is only possible with this workflow:
1. `git clone https://github.com/sobolevn/git-secret.git`
2. `make develop`
3. then move the resulting file `git-secret` somewhere inside your `PATH`
[1]: https://github.com/sstephenson/bats

BIN
gh-pages/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,3 @@
_site
.sass-cache
.jekyll-metadata

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

@ -0,0 +1,18 @@
# Welcome to Jekyll!
#
# This config file is meant for settings that affect your whole blog, values
# which you are expected to set up once and rarely need to edit after that.
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'jekyll serve'. If you change this file, please restart the server process.
# Site settings
title: git-secret
email: mail@sobolevn.me
description: > # this means to ignore newlines until "baseurl:"
store your private data inside a git repository.
baseurl: "" # the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site
github_username: sobolevn
# Build settings
markdown: kramdown

@ -0,0 +1,38 @@
<footer class="site-footer">
<div class="wrapper">
<h2 class="footer-heading">{{ site.title }}</h2>
<div class="footer-col-wrapper">
<div class="footer-col footer-col-1">
<ul class="contact-list">
<li>{{ site.title }}</li>
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
</ul>
</div>
<div class="footer-col footer-col-2">
<ul class="social-media-list">
{% if site.github_username %}
<li>
{% include icon-github.html username=site.github_username %}
</li>
{% endif %}
{% if site.twitter_username %}
<li>
{% include icon-twitter.html username=site.twitter_username %}
</li>
{% endif %}
</ul>
</div>
<div class="footer-col footer-col-3">
<p>{{ site.description }}</p>
</div>
</div>
</div>
</footer>

@ -0,0 +1,12 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}">
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}">
</head>

@ -0,0 +1,27 @@
<header class="site-header">
<div class="wrapper">
<a class="site-title" href="{{ site.baseurl }}/">{{ site.title }}</a>
<nav class="site-nav">
<a href="#" class="menu-icon">
<svg viewBox="0 0 18 15">
<path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/>
<path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/>
<path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/>
</svg>
</a>
<div class="trigger">
{% for my_page in site.pages %}
{% if my_page.title %}
<a class="page-link" href="{{ my_page.url | prepend: site.baseurl }}">{{ my_page.title }}</a>
{% endif %}
{% endfor %}
</div>
</nav>
</div>
</header>

@ -0,0 +1 @@
<a href="https://github.com/{{ include.username }}"><span class="icon icon--github">{% include icon-github.svg %}</span><span class="username">{{ include.username }}</span></a>

@ -0,0 +1 @@
<svg viewBox="0 0 16 16"><path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/></svg>

After

Width:  |  Height:  |  Size: 926 B

@ -0,0 +1 @@
<a href="https://twitter.com/{{ include.username }}"><span class="icon icon--twitter">{% include icon-twitter.svg %}</span><span class="username">{{ include.username }}</span></a>

@ -0,0 +1 @@
<svg viewBox="0 0 16 16"><path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/></svg>

After

Width:  |  Height:  |  Size: 787 B

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
{% include head.html %}
<body>
{% include header.html %}
<div class="page-content">
<div class="wrapper">
{{ content }}
</div>
</div>
{% include footer.html %}
</body>
</html>

@ -0,0 +1,14 @@
---
layout: default
---
<article class="post">
<header class="post-header">
<h1 class="post-title">{{ page.title }}</h1>
</header>
<div class="post-content">
{{ content }}
</div>
</article>

@ -0,0 +1,15 @@
---
layout: default
---
<article class="post" itemscope itemtype="http://schema.org/BlogPosting">
<header class="post-header">
<h1 class="post-title" itemprop="name headline">{{ page.title }}</h1>
<p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time>{% if page.author %} • <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">{{ page.author }}</span></span>{% endif %}</p>
</header>
<div class="post-content" itemprop="articleBody">
{{ content }}
</div>
</article>

Binary file not shown.

@ -0,0 +1,25 @@
---
layout: post
title: "Welcome to Jekyll!"
date: 2016-01-18 10:40:25 +0300
categories:
---
Youll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
Jekyll also offers powerful support for code snippets:
{% highlight ruby %}
def print_hi(name)
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endhighlight %}
Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekylls GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
[jekyll-docs]: http://jekyllrb.com/docs/home
[jekyll-gh]: https://github.com/jekyll/jekyll
[jekyll-talk]: https://talk.jekyllrb.com/

@ -0,0 +1,206 @@
/**
* Reset some basic elements
*/
body, h1, h2, h3, h4, h5, h6,
p, blockquote, pre, hr,
dl, dd, ol, ul, figure {
margin: 0;
padding: 0;
}
/**
* Basic styling
*/
body {
font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family;
color: $text-color;
background-color: $background-color;
-webkit-text-size-adjust: 100%;
-webkit-font-feature-settings: "kern" 1;
-moz-font-feature-settings: "kern" 1;
-o-font-feature-settings: "kern" 1;
font-feature-settings: "kern" 1;
font-kerning: normal;
}
/**
* Set `margin-bottom` to maintain vertical rhythm
*/
h1, h2, h3, h4, h5, h6,
p, blockquote, pre,
ul, ol, dl, figure,
%vertical-rhythm {
margin-bottom: $spacing-unit / 2;
}
/**
* Images
*/
img {
max-width: 100%;
vertical-align: middle;
}
/**
* Figures
*/
figure > img {
display: block;
}
figcaption {
font-size: $small-font-size;
}
/**
* Lists
*/
ul, ol {
margin-left: $spacing-unit;
}
li {
> ul,
> ol {
margin-bottom: 0;
}
}
/**
* Headings
*/
h1, h2, h3, h4, h5, h6 {
font-weight: $base-font-weight;
}
/**
* Links
*/
a {
color: $brand-color;
text-decoration: none;
&:visited {
color: darken($brand-color, 15%);
}
&:hover {
color: $text-color;
text-decoration: underline;
}
}
/**
* Blockquotes
*/
blockquote {
color: $purple-color;
border-left: 4px solid $purple-color-light;
padding-left: $spacing-unit / 2;
font-size: 18px;
letter-spacing: -1px;
font-style: italic;
> :last-child {
margin-bottom: 0;
}
}
/**
* Code formatting
*/
pre,
code {
font-size: 15px;
border: 1px solid $purple-color-light;
border-radius: 3px;
background-color: #eef;
}
code {
padding: 1px 5px;
}
pre {
padding: 8px 12px;
overflow-x: auto;
> code {
border: 0;
padding-right: 0;
padding-left: 0;
}
}
/**
* Wrapper
*/
.wrapper {
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
margin-right: auto;
margin-left: auto;
padding-right: $spacing-unit;
padding-left: $spacing-unit;
@extend %clearfix;
@include media-query($on-laptop) {
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
max-width: calc(#{$content-width} - (#{$spacing-unit}));
padding-right: $spacing-unit / 2;
padding-left: $spacing-unit / 2;
}
}
/**
* Clearfix
*/
%clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
/**
* Icons
*/
.icon {
> svg {
display: inline-block;
width: 16px;
height: 16px;
vertical-align: middle;
path {
fill: $purple-color;
}
}
}

@ -0,0 +1,242 @@
/**
* Site header
*/
.site-header {
border-top: 5px solid $purple-color-dark;
border-bottom: 1px solid $purple-color-light;
min-height: 56px;
// Positioning context for the mobile navigation icon
position: relative;
}
.site-title {
font-size: 26px;
font-weight: 300;
line-height: 56px;
letter-spacing: -1px;
margin-bottom: 0;
float: left;
&,
&:visited {
color: $purple-color-dark;
}
}
.site-nav {
float: right;
line-height: 56px;
.menu-icon {
display: none;
}
.page-link {
color: $text-color;
line-height: $base-line-height;
// Gaps between nav items, but not on the last one
&:not(:last-child) {
margin-right: 20px;
}
}
@include media-query($on-palm) {
position: absolute;
top: 9px;
right: $spacing-unit / 2;
background-color: $background-color;
border: 1px solid $purple-color-light;
border-radius: 5px;
text-align: right;
.menu-icon {
display: block;
float: right;
width: 36px;
height: 26px;
line-height: 0;
padding-top: 10px;
text-align: center;
> svg {
width: 18px;
height: 15px;
path {
fill: $purple-color-dark;
}
}
}
.trigger {
clear: both;
display: none;
}
&:hover .trigger {
display: block;
padding-bottom: 5px;
}
.page-link {
display: block;
padding: 5px 10px;
&:not(:last-child) {
margin-right: 0;
}
margin-left: 20px;
}
}
}
/**
* Site footer
*/
.site-footer {
border-top: 1px solid $purple-color-light;
padding: $spacing-unit 0;
}
.footer-heading {
font-size: 18px;
margin-bottom: $spacing-unit / 2;
}
.contact-list,
.social-media-list {
list-style: none;
margin-left: 0;
}
.footer-col-wrapper {
font-size: 15px;
color: $grey-color;
margin-left: -$spacing-unit / 2;
@extend %clearfix;
}
.footer-col {
float: left;
margin-bottom: $spacing-unit / 2;
padding-left: $spacing-unit / 2;
}
.footer-col-1 {
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
width: calc(35% - (#{$spacing-unit} / 2));
}
.footer-col-2 {
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
width: calc(20% - (#{$spacing-unit} / 2));
}
.footer-col-3 {
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
width: calc(45% - (#{$spacing-unit} / 2));
}
@include media-query($on-laptop) {
.footer-col-1,
.footer-col-2 {
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
width: calc(50% - (#{$spacing-unit} / 2));
}
.footer-col-3 {
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
width: calc(100% - (#{$spacing-unit} / 2));
}
}
@include media-query($on-palm) {
.footer-col {
float: none;
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
width: calc(100% - (#{$spacing-unit} / 2));
}
}
/**
* Page content
*/
.page-content {
padding: $spacing-unit 0;
}
.page-heading {
font-size: 20px;
}
.post-list {
margin-left: 0;
list-style: none;
> li {
margin-bottom: $spacing-unit;
}
}
.post-meta {
font-size: $small-font-size;
color: $grey-color;
}
.post-link {
display: block;
font-size: 24px;
}
/**
* Posts
*/
.post-header {
margin-bottom: $spacing-unit;
}
.post-title {
font-size: 42px;
letter-spacing: -1px;
line-height: 1;
@include media-query($on-laptop) {
font-size: 36px;
}
}
.post-content {
margin-bottom: $spacing-unit;
h2 {
font-size: 32px;
@include media-query($on-laptop) {
font-size: 28px;
}
}
h3 {
font-size: 26px;
@include media-query($on-laptop) {
font-size: 22px;
}
}
h4 {
font-size: 20px;
@include media-query($on-laptop) {
font-size: 18px;
}
}
}

@ -0,0 +1,71 @@
/**
* Syntax highlighting styles
*/
.highlight {
background: #fff;
@extend %vertical-rhythm;
.highlighter-rouge & {
background: #eef;
}
.c { color: #998; font-style: italic } // Comment
.err { color: #a61717; background-color: #e3d2d2 } // Error
.k { font-weight: bold } // Keyword
.o { font-weight: bold } // Operator
.cm { color: #998; font-style: italic } // Comment.Multiline
.cp { color: #999; font-weight: bold } // Comment.Preproc
.c1 { color: #998; font-style: italic } // Comment.Single
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
.gd { color: #000; background-color: #fdd } // Generic.Deleted
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
.ge { font-style: italic } // Generic.Emph
.gr { color: #a00 } // Generic.Error
.gh { color: #999 } // Generic.Heading
.gi { color: #000; background-color: #dfd } // Generic.Inserted
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
.go { color: #888 } // Generic.Output
.gp { color: #555 } // Generic.Prompt
.gs { font-weight: bold } // Generic.Strong
.gu { color: #aaa } // Generic.Subheading
.gt { color: #a00 } // Generic.Traceback
.kc { font-weight: bold } // Keyword.Constant
.kd { font-weight: bold } // Keyword.Declaration
.kp { font-weight: bold } // Keyword.Pseudo
.kr { font-weight: bold } // Keyword.Reserved
.kt { color: #458; font-weight: bold } // Keyword.Type
.m { color: #099 } // Literal.Number
.s { color: #d14 } // Literal.String
.na { color: #008080 } // Name.Attribute
.nb { color: #0086B3 } // Name.Builtin
.nc { color: #458; font-weight: bold } // Name.Class
.no { color: #008080 } // Name.Constant
.ni { color: #800080 } // Name.Entity
.ne { color: #900; font-weight: bold } // Name.Exception
.nf { color: #900; font-weight: bold } // Name.Function
.nn { color: #555 } // Name.Namespace
.nt { color: #000080 } // Name.Tag
.nv { color: #008080 } // Name.Variable
.ow { font-weight: bold } // Operator.Word
.w { color: #bbb } // Text.Whitespace
.mf { color: #099 } // Literal.Number.Float
.mh { color: #099 } // Literal.Number.Hex
.mi { color: #099 } // Literal.Number.Integer
.mo { color: #099 } // Literal.Number.Oct
.sb { color: #d14 } // Literal.String.Backtick
.sc { color: #d14 } // Literal.String.Char
.sd { color: #d14 } // Literal.String.Doc
.s2 { color: #d14 } // Literal.String.Double
.se { color: #d14 } // Literal.String.Escape
.sh { color: #d14 } // Literal.String.Heredoc
.si { color: #d14 } // Literal.String.Interpol
.sx { color: #d14 } // Literal.String.Other
.sr { color: #009926 } // Literal.String.Regex
.s1 { color: #d14 } // Literal.String.Single
.ss { color: #990073 } // Literal.String.Symbol
.bp { color: #999 } // Name.Builtin.Pseudo
.vc { color: #008080 } // Name.Variable.Class
.vg { color: #008080 } // Name.Variable.Global
.vi { color: #008080 } // Name.Variable.Instance
.il { color: #099 } // Literal.Number.Integer.Long
}

@ -0,0 +1,15 @@
---
layout: page
title: About
permalink: /about/
---
This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](http://jekyllrb.com/)
You can find the source code for the Jekyll new theme at:
{% include icon-github.html username="jglovier" %} /
[jekyll-new](https://github.com/jglovier/jekyll-new)
You can find the source code for Jekyll at
{% include icon-github.html username="jekyll" %} /
[jekyll](https://github.com/jekyll/jekyll)

@ -0,0 +1,58 @@
---
# Only the main Sass file needs front matter (the dashes are enough)
---
@charset "utf-8";
// Our variables
$base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
$base-font-size: 16px;
$base-font-weight: 400;
$small-font-size: $base-font-size * 0.875;
$base-line-height: 1.5;
$spacing-unit: 30px;
$text-color: #111;
$background-color: #fdfdfd;
$grey-color: #828282;
$grey-color-light: lighten($grey-color, 40%);
$grey-color-dark: darken($grey-color, 25%);
$purple-color: #9b4dca;
$purple-color-light: lighten($purple-color, 40%);
$purple-color-dark: darken($purple-color, 25%);
$brand-color: $purple-color;
// Width of the content area
$content-width: 800px;
$on-palm: 600px;
$on-laptop: 800px;
// Use media queries like this:
// @include media-query($on-palm) {
// .wrapper {
// padding-right: $spacing-unit / 2;
// padding-left: $spacing-unit / 2;
// }
// }
@mixin media-query($device) {
@media screen and (max-width: $device) {
@content;
}
}
// Import partials from `sass_dir` (defaults to `_sass`)
@import
"base",
"layout",
"syntax-highlighting"
;

@ -0,0 +1,30 @@
---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ site.title | xml_escape }}</title>
<description>{{ site.description | xml_escape }}</description>
<link>{{ site.url }}{{ site.baseurl }}/</link>
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
<generator>Jekyll v{{ jekyll.version }}</generator>
{% for post in site.posts limit:10 %}
<item>
<title>{{ post.title | xml_escape }}</title>
<description>{{ post.content | xml_escape }}</description>
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
<link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>
<guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
{% for tag in post.tags %}
<category>{{ tag | xml_escape }}</category>
{% endfor %}
{% for cat in post.categories %}
<category>{{ cat | xml_escape }}</category>
{% endfor %}
</item>
{% endfor %}
</channel>
</rss>

@ -0,0 +1,21 @@
---
layout: default
---
<div class="home">
<h1 class="page-heading">Posts</h1>
<ul class="post-list">
{% for post in site.posts %}
<li>
<h2>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
</h2>
</li>
{% endfor %}
</ul>
<p class="rss-subscribe">subscribe <a href="{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
</div>

@ -0,0 +1,651 @@
#!/usr/bin/env bash
# Global variables:
WORKING_DIRECTORY="$PWD"
# Folders:
SECRETS_DIR=".gitsecret"
SECRETS_DIR_KEYS="$SECRETS_DIR/keys"
SECRETS_DIR_PATHS="$SECRETS_DIR/paths"
# Files:
SECRETS_DIR_KEYS_MAPPING="$SECRETS_DIR_KEYS/mapping.cfg"
SECRETS_DIR_KEYS_PUBRING="$SECRETS_DIR_KEYS/pubring.gpg"
SECRETS_DIR_KEYS_TRUSTDB="$SECRETS_DIR_KEYS/trustdb.gpg"
SECRETS_DIR_PATHS_MAPPING="$SECRETS_DIR_PATHS/mapping.cfg"
: ${SECRETS_GPG_COMMAND:="gpg"}
GPGLOCAL="$SECRETS_GPG_COMMAND --homedir=$SECRETS_DIR_KEYS --no-permission-warning"
: ${SECRETS_EXTENSION:=".secret"}
# Inner bash :
function _function_exists {
declare -f -F "$1" > /dev/null
echo $?
}
# OS based :
function _os_based {
# Pass function name as first parameter.
# It will be invoked as os-based function with the postfix.
case "$(uname -s)" in
Darwin)
$1_osx ${@:2}
;;
Linux)
$1_linux ${@:2}
;;
# TODO: add MS Windows support.
# CYGWIN*|MINGW32*|MSYS*)
# $1_ms ${@:2}
# ;;
*)
_abort 'unsupported OS.'
;;
esac
}
# File System :
function _set_config {
# First parameter is the KEY, second is VALUE, third is filename.
# The exit status is 0 (true) if the name was found, 1 (false) if not:
local contains=$(grep -Fq "$1" $3; echo $?)
if [[ "$contains" -eq 0 ]]; then
_os_based __replace_in_file $@
elif [[ "$contains" -eq 1 ]]; then
echo "$1 = $2" >> "$3"
fi
}
function _file_has_line {
# First parameter is the KEY, second is the filename.
local contains=$(grep -qw "$1" "$2"; echo $?)
# 0 on contains, 1 for error.
echo "$contains";
}
function _delete_line {
_os_based __delete_line $@
}
function _temporary_file {
# This function creates temporary file
# which will be removed on system exit.
filename=$(_os_based __temp_file) # is not `local` on purpose.
trap "echo 'cleaning up...'; rm -f $filename;" EXIT
}
function _unique_filename {
# First parameter is base-path, second is filename,
# third is optional extension.
local n=0 result=$2
while [[ 1 ]]; do
if [[ ! -f "$1/$result" ]]; then
break
fi
n=$(( $n + 1 ))
result="$2-$n"
done
echo $result
}
# VCS :
function _check_ignore {
git check-ignore -q "$1";
echo $?
}
# Logic :
function _abort {
>&2 echo "$1 abort."
exit 1
}
function _secrets_dir_exists {
if [[ ! -d $SECRETS_DIR ]]; then
_abort "$SECRETS_DIR does not exist."
fi
}
function _user_required {
_secrets_dir_exists
local error_message="no users found. run 'git secret tell' before adding files."
if [[ ! -f "$SECRETS_DIR_KEYS_PUBRING" ]] ||
[[ ! -f "$SECRETS_DIR_KEYS_TRUSTDB" ]]; then
_abort "$error_message"
fi
local keys_exist=$($GPGLOCAL -n --list-keys --with-colon)
if [[ -z $keys_exist ]]; then
_abort "$error_message"
fi
}
function _get_raw_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")" | sed -e 's#^\./##'
}
function _get_encrypted_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")$SECRETS_EXTENSION" | sed -e 's#^\./##'
}
function _get_users_in_keyring {
local result=$($GPGLOCAL --list-public-keys --with-colon | sed -n 's/.*<\(.*\)>.*/\1/p')
echo "$result"
}
function _get_recepients {
local result=$($GPGLOCAL --list-public-keys --with-colon | sed -n 's/.*<\(.*\)>.*/-r\1/p')
echo "$result"
}
#!/usr/bin/env bash
function __replace_in_file_linux {
sed -i.bak "s/^\($1\s*=\s*\).*\$/\1$2/" "$3"
}
function __delete_line_linux {
sed -i.bak "/$1/d" "$2"
}
function __temp_file_linux {
local filename=$(mktemp)
echo "$filename"
}
#!/usr/bin/env bash
function __replace_in_file_osx {
sed -i.bak "s/^\($1[[:space:]]*=[[:space:]]*\).*\$/\1$2/" "$3"
}
function __delete_line_osx {
sed -i.bak "/$1/d" "$2"
}
function __temp_file_osx {
: "${TMPDIR:=/tmp}"
local filename=$(mktemp -t _gitsecrets_ )
echo "$filename";
}
#!/usr/bin/env bash
function add {
_user_required
local not_ignored=()
for item in $@; do
# Checking if all files in options are ignored:
if [[ ! -f "$item" ]]; then
_abort "$item is not a file."
fi
local ignored=$(_check_ignore "$item")
if [[ ! "$ignored" -eq 0 ]]; then
# collect unignored files.
not_ignored+=("$item")
fi
done
if [[ ! "${#not_ignored[@]}" -eq 0 ]]; then
# and show them all at once.
_abort "these files are not ignored: ${not_ignored[@]} ;"
fi
for item in $@; do
# adding files into system, skipping duplicates.
local already_in=$(_file_has_line "$item" "$SECRETS_DIR_PATHS_MAPPING")
if [[ "$already_in" -eq 1 ]]; then
echo "$item" >> "$SECRETS_DIR_PATHS_MAPPING"
fi
done
echo "${#@} items added."
}
#!/usr/bin/env bash
function _show_help_clean {
cat <<-EOF
usage: git secret clean [-v]
removes all the hidden files.
options:
-v shows which files are deleted.
-h shows this help.
EOF
exit 0
}
function clean {
OPTIND=1
local verbose=""
while getopts "vh" opt; do
case "$opt" in
v)
verbose="v"
;;
h)
_show_help_clean
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
[[ ! -z $verbose ]] && echo && echo "cleaing:" || : # bug with custom bash on OSX
find . -name *$SECRETS_EXTENSION -type f | xargs rm -f$verbose
[[ ! -z $verbose ]] && echo || : # bug with custom bash on OSX
}
#!/usr/bin/env bash
function _show_help_hide {
cat <<-EOF
usage: git secret hide [-c] [-v]
encrypts all the files added by the 'add' command.
options:
-c deletes encrypted files before creating new ones.
-v shows which files are deleted.
-h shows this help.
EOF
exit 0
}
function _optional_clean {
OPTIND=1
local clean=0
local opt_string=""
while getopts "cvh" opt; do
case "$opt" in
c) clean=1;;
h) _show_help_hide;;
v) opt_string="-v";;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
_user_required
if [[ $clean -eq 1 ]]; then
clean "$opt_string"
fi
}
function hide {
_optional_clean $@
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename $line)
local recipients=$(_get_recepients)
$GPGLOCAL --use-agent --yes --trust-model=always --encrypt $recipients -o "$encrypted_filename" "$line"
counter=$((counter+1))
done < "$SECRETS_DIR_PATHS_MAPPING"
echo "done. all $counter files are hidden."
}
#!/usr/bin/env bash
function init {
if [[ -d "$SECRETS_DIR" ]]; then
_abort "already inited."
fi
local ignores=$(_check_ignore "$SECRETS_DIR"/)
if [[ ! $ignores -eq 1 ]]; then
_abort "'${SECRETS_DIR}/' is ignored."
fi
mkdir "$SECRETS_DIR" "$SECRETS_DIR_KEYS" "$SECRETS_DIR_PATHS"
touch "$SECRETS_DIR_KEYS_MAPPING" "$SECRETS_DIR_PATHS_MAPPING"
echo "'${SECRETS_DIR}/' created."
}
#!/usr/bin/env bash
function killperson {
_user_required
if [[ ${#@} -eq 0 ]]; then
_abort "email is required."
fi
$GPGLOCAL --batch --yes --delete-key "$1"
}
#!/usr/bin/env bash
function list {
_user_required
if [[ ! -s "$SECRETS_DIR_PATHS_MAPPING" ]]; then
exit 1
fi
while read line; do
echo "$line"
done < "$SECRETS_DIR_PATHS_MAPPING"
}
#!/usr/bin/env bash
function _show_help_remove {
cat <<-EOF
usage: git secret remove [-c] <pathspec..>
removes files from git-secret's index."
options:
-c deletes existing real encrypted files.
-h shows this help.
EOF
exit 0
}
function remove {
OPTIND=1
local clean=0
while getopts "ch" opt; do
case "$opt" in
c) clean=1;;
h) _show_help_remove;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# validate if user exist:
_user_required
for item in $@; do
if [[ ! -f "$item" ]]; then
_abort "$item is not a file."
fi
_delete_line "$item" "$SECRETS_DIR_PATHS_MAPPING"
rm -f "${SECRETS_DIR_PATHS_MAPPING}.bak"
if [[ "$clean" == 1 ]]; then
local encrypted_filename=$(_get_encrypted_filename "$item")
rm -f "$encrypted_filename"
fi
done
local all=${@}
echo "removed from index."
echo "ensure that files: [$all] are now not ignored."
}
#!/usr/bin/env bash
function _show_help_reveal {
cat <<-EOF
usage: git secret reveal [-d dir] [-p password]
unencrypts all the files added by the 'add' command.
options:
-d specifies --homedir option for gpg.
-p specifies password for noinput mode, adds --passphrase option for gpg.
-h shows this help.
EOF
exit 0
}
function reveal {
OPTIND=1
local homedir=""
local passphrase=""
while getopts "hd:p:" opt; do
case "$opt" in
h) _show_help_reveal;;
p) passphrase=$OPTARG;;
d) homedir=$OPTARG;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
_user_required
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename "$line")
local base="$SECRETS_GPG_COMMAND --use-agent -q --decrypt"
if [[ ! -z "$homedir" ]]; then
base="$base --homedir=$homedir"
fi
if [[ ! -z "$passphrase" ]]; then
base="$base --batch --yes --passphrase $passphrase"
fi
$base -o "$line" "$encrypted_filename"
counter=$((counter+1))
done < "$SECRETS_DIR_PATHS_MAPPING"
echo "done. all $counter files are revealed."
}
#!/usr/bin/env bash
function _show_help_tell {
cat <<-EOF
usage: git secret tell [-m] [-d dir] [email]
adds a person, who can access the private data.
options:
-m - takes your current 'git config user.email' as an identifier for the key.
-d - specifies '--homedir' option for the 'gpg'
-h shows this help.
EOF
exit 0
}
function tell {
_secrets_dir_exists
# A POSIX variable
# Reset in case getopts has been used previously in the shell.
OPTIND=1
local email
local homedir
while getopts "h?md:" opt; do
case "$opt" in
h) _show_help_tell;;
m) # Set email of the git current user:
email=$(git config user.email) || _abort "'git congig user.email' is not set."
;;
d) homedir=$OPTARG;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# Custom argument-parsing:
if [[ -z $email ]]; then
# Email was not set via `-m` and is in $1:
test ! -z "$1" && email="$1"; shift || _abort "first argument must be an email address."
fi
# This file will be removed automatically:
_temporary_file
local keyfile="$filename"
if [[ -z "$homedir" ]]; then
$SECRETS_GPG_COMMAND --export -a "$email" > "$keyfile"
else
# It means that homedir is set as an extra argument via `-d`:
$SECRETS_GPG_COMMAND --no-permission-warning --homedir="$homedir" --export -a "$email" > "$keyfile"
fi
if [[ ! -s "$keyfile" ]]; then
_abort 'gpg key is empty. check your key name: `gpg --list-keys`.'
fi
# Importing public key to the local keychain:
$GPGLOCAL --import "$keyfile" > /dev/null 2>&1
echo "done. $email added as a person who knows the secret."
}
#!/usr/bin/env bash
function usage {
local commands=""
local separator="|"
for com in $(compgen -A function); do
if [[ ! $com == _* ]]; then
commands+="$com$separator"
fi
done
echo "usage: git secret [${commands%?}]"
}
#!/usr/bin/env bash
function whoknows {
_user_required
local keys=$(_get_users_in_keyring)
echo "$keys"
}
#!/usr/bin/env bash
function _check_setup {
# Checking git and secret-plugin setup:
if [[ ! -d ".git" ]] || [[ ! -d ".git/hooks" ]]; then
_abort "repository is broken. try running 'git init' or 'git clone'."
fi
# Checking if the '.gitsecret' is not ignored:
local ignored=$(_check_ignore ".gitsecret/")
if [[ ! $ignored -eq 1 ]]; then
_abort ".gitsecret folder is ignored."
fi
# Checking gpg setup:
local secring="$SECRETS_DIR_KEYS/secring.gpg"
if [[ -f $secring ]] && [[ -s $secring ]]; then
# secring.gpg is not empty, someone has imported a private key.
_abort "it seems that someone has imported a secret key."
fi
}
function _incorrect_usage {
echo "$1"
usage
exit "$2"
}
function _init_script {
# checking for proper set-up:
_check_setup
if [[ $# == 0 ]]; then
_incorrect_usage "no input parameters provided." 126
fi
# load dependencies:
# for f in ${0%/*}/src/*/*; do [[ -f "$f" ]] && . "$f"; done
# routing the input command:
if [[ $(_function_exists "$1") == 0 ]] && [[ ! $1 == _* ]]; then
$1 "${@:2}"
else
_incorrect_usage "command $1 not found." 126
fi
}
set -e
_init_script $@

BIN
man/.DS_Store vendored

Binary file not shown.

BIN
man/man1/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,27 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SECRET\-ADD" "1" "February 2016" "" ""
.
.SH "NAME"
\fBgit\-secret\-add\fR \- starts to track added files\.
.
.SH "SYNOPSIS"
.
.nf
git secret add [<pathspec>\.\.\.]
.
.fi
.
.SH "DESCRIPTION"
\fBgit\-secret\-add\fR adds a filepath(es) into the \fB\.gitsecret/paths/mapping\.cfg\fR\. When adding files, ensure that they are ignored by \fBgit\fR, since they must be secure and not be commited into the remote repository unencrypted\.
.
.P
If there\'s no users in the \fBgit\-secret\fR\'s keyring, when adding a file, an exception will be raised\.
.
.P
It is not recommened to add filenames directly into the \fB\.gitsecret/paths/mapping\.cfg\fR, use the command\.
.
.SH "SEE ALSO"
git\-secret\-init(1), git\-secret\-tell(1), git\-secret\-hide(1), git\-secret\-reveal(1)

@ -0,0 +1,18 @@
git-secret-add - starts to track added files.
=============================================
## SYNOPSIS
git secret add [<pathspec>...]
## DESCRIPTION
`git-secret-add` adds a filepath(es) into the `.gitsecret/paths/mapping.cfg`. When adding files, ensure that they are ignored by `git`, since they must be secure and not be commited into the remote repository unencrypted.
If there's no users in the `git-secret`'s keyring, when adding a file, an exception will be raised.
It is not recommened to add filenames directly into the `.gitsecret/paths/mapping.cfg`, use the command.
## SEE ALSO
git-secret-init(1), git-secret-tell(1), git-secret-hide(1), git-secret-reveal(1)

@ -0,0 +1,34 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SECRET\-HIDE" "1" "February 2016" "" ""
.
.SH "NAME"
\fBgit\-secret\-hide\fR \- encrypts all added files with the inner keyring\.
.
.SH "SYNOPSIS"
.
.nf
git secret hide [\-c] [\-v] [\-h]
.
.fi
.
.SH "DESCRIPTION"
\fBgit\-secret\-hide\fR create an encrypted version for each file added by \fBgit\-secret\-add\fR command\. Now anyone one from the \fBgit\-secret\fR\'s keyring can decrypt these files using the their secret key\.
.
.P
It is possible to modify the names of the encrypted files by setting \fBSECRETS_EXTENSION\fR variable\.
.
.SH "OPTIONS"
.
.nf
\-v \- verbose, shows extra information\.
\-c \- deletes encrypted files before creating new ones\.
\-h \- shows help\.
.
.fi
.
.SH "SEE ALSO"
git\-secret\-init(1), git\-secret\-tell(1), git\-secret\-add(1), git\-secret\-reveal(1)

@ -0,0 +1,24 @@
git-secret-hide - encrypts all added files with the inner keyring.
==================================================================
## SYNOPSIS
git secret hide [-c] [-v]
## DESCRIPTION
`git-secret-hide` create an encrypted version for each file added by `git-secret-add` command. Now anyone one from the `git-secret`'s keyring can decrypt these files using the their secret key.
It is possible to modify the names of the encrypted files by setting `SECRETS_EXTENSION` variable.
## OPTIONS
-v - verbose, shows extra information.
-c - deletes encrypted files before creating new ones.
-h - shows help.
## SEE ALSO
git-secret-init(1), git-secret-tell(1), git-secret-add(1), git-secret-reveal(1)

@ -0,0 +1,21 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SECRET\-INIT" "1" "February 2016" "" ""
.
.SH "NAME"
\fBgit\-secret\-init\fR \- initializes git\-secret repository\.
.
.SH "SYNOPSIS"
.
.nf
git secret init
.
.fi
.
.SH "DESCRIPTION"
\fBgit\-secret\-init\fR should be runned inside a \fBgit\fR repo\. \fBgit\-secret\-init\fR is the first command to be runned, until the git\-secret repository is inited other commands are unavailable\.
.
.SH "SEE ALSO"
git\-init(1), git\-secret\-tell(1)

@ -0,0 +1,15 @@
git-secret-init - initializes git-secret repository.
====================================================
## SYNOPSIS
git secret init
## DESCRIPTION
`git-secret-init` should be runned inside a `git` repo. `git-secret-init` is the first command to be runned, until the git-secret repository is inited other commands are unavailable.
## SEE ALSO
git-init(1), git-secret-tell(1)

@ -0,0 +1,21 @@
git-secret-remove - removes files from index.
=============================================
## SYNOPSIS
git secret remove [-c] <pathspec..>
## DESCRIPTION
`git-secret-remove` deletes files from `.gitsecret/paths/mapping.cfg`, so they won't be encrypted or decrypted in the future. There's also an option to delete existing encrypted versions of the files provided.
## OPTIONS
-c - deletes existing real encrypted files.
-h - shows help.
## SEE ALSO
git-secret-add(1), git-secret-reveal(1), git-secret-hide(1)

@ -0,0 +1,31 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SECRET\-REVEAL" "1" "February 2016" "" ""
.
.SH "NAME"
\fBgit\-secret\-reveal\fR \- decrypts all added files\.
.
.SH "SYNOPSIS"
.
.nf
git secret reveal [\-p] [\-d] [\-h]
.
.fi
.
.SH "DESCRIPTION"
\fBgit\-secret\-reveal\fR \- decrypts all the files in the \fB\.gitsecret/paths/mapping\.cfg\fR by running a \fBgpg \-\-decrypt\fR command\. It is important to have paired secret\-key for one of the public\-keys, which were used in the encryption\.
.
.SH "OPTIONS"
.
.nf
\-d \- specifies `\-\-homedir` option for the `gpg`, basically use this option if your store your keys in a custom location\.
\-p \- specifies password for noinput mode, adds `\-\-passphrase` option for `gpg`\.
\-h \- shows help\.
.
.fi
.
.SH "SEE ALSO"
git\-secret\-init(1), git\-secret\-tell(1), git\-secret\-add(1), git\-secret\-hide(1)

@ -0,0 +1,22 @@
git-secret-reveal - decrypts all added files.
=============================================
## SYNOPSIS
git secret reveal [-d dir] [-p password]
## DESCRIPTION
`git-secret-reveal` - decrypts all the files in the `.gitsecret/paths/mapping.cfg` by running a `gpg --decrypt` command. It is important to have paired secret-key for one of the public-keys, which were used in the encryption.
## OPTIONS
-d - specifies `--homedir` option for the `gpg`, basically use this option if your store your keys in a custom location.
-p - specifies password for noinput mode, adds `--passphrase` option for `gpg`.
-h - shows help.
## SEE ALSO
git-secret-init(1), git-secret-tell(1), git-secret-add(1), git-secret-hide(1)

@ -0,0 +1,34 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-SECRET\-TELL" "1" "February 2016" "" ""
.
.SH "NAME"
\fBgit\-secret\-tell\fR \- adds a person, who can access a private data\.
.
.SH "SYNOPSIS"
.
.nf
git secret tell [\-m] [\-d] [\-h]
.
.fi
.
.SH "DESCRIPTION"
\fBgit\-secret\-tell\fR receives an email address as an input, searches for the \fBgpg\fR\-key in the \fBgpg\fR\'s \fBhomedir\fR by this email, then import a person\'s public key into the \fBgit\-secret\fR\'s inner keychain\. Since this moment this person can encrypt new files with the keyring which contains his key\. But he cannot decrypt the old files, which were already encrypted without his key\. They should be reencrypted with the new keyring by someone, who has the unencrypted files\.
.
.P
\fBDo not manually import secret key into \fBgit\-secret\fR\fR\. Anyway, it won\'t work with any of the secret\-keys imported\.
.
.SH "OPTIONS"
.
.nf
\-m \- takes your current `git config user\.email` as an identifier for the key\.
\-d \- specifies `\-\-homedir` option for the `gpg`, basically use this option if your store your keys in a custom location\.
\-h \- shows help\.
.
.fi
.
.SH "SEE ALSO"
git\-secret\-init(1), git\-secret\-add(1), git\-secret\-hide(1), git\-secret\-reveal(1)

@ -0,0 +1,24 @@
git-secret-tell - adds a person, who can access a private data.
===============================================================
## SYNOPSIS
git secret tell [-m] [-d dir] [email]
## DESCRIPTION
`git-secret-tell` receives an email address as an input, searches for the `gpg`-key in the `gpg`'s `homedir` by this email, then import a person's public key into the `git-secret`'s inner keychain. Since this moment this person can encrypt new files with the keyring which contains his key. But he cannot decrypt the old files, which were already encrypted without his key. They should be reencrypted with the new keyring by someone, who has the unencrypted files.
**Do not manually import secret key into `git-secret`**. Anyway, it won't work with any of the secret-keys imported.
## OPTIONS
-m - takes your current `git config user.email` as an identifier for the key.
-d - specifies `--homedir` option for the `gpg`, basically use this option if your store your keys in a custom location.
-h - shows help.
## SEE ALSO
git-secret-init(1), git-secret-add(1), git-secret-hide(1), git-secret-reveal(1)

BIN
src/.DS_Store vendored

Binary file not shown.

BIN
src/_utils/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,173 @@
#!/usr/bin/env bash
# Global variables:
WORKING_DIRECTORY="$PWD"
# Folders:
SECRETS_DIR=".gitsecret"
SECRETS_DIR_KEYS="$SECRETS_DIR/keys"
SECRETS_DIR_PATHS="$SECRETS_DIR/paths"
# Files:
SECRETS_DIR_KEYS_MAPPING="$SECRETS_DIR_KEYS/mapping.cfg"
SECRETS_DIR_KEYS_PUBRING="$SECRETS_DIR_KEYS/pubring.gpg"
SECRETS_DIR_KEYS_TRUSTDB="$SECRETS_DIR_KEYS/trustdb.gpg"
SECRETS_DIR_PATHS_MAPPING="$SECRETS_DIR_PATHS/mapping.cfg"
: ${SECRETS_GPG_COMMAND:="gpg"}
GPGLOCAL="$SECRETS_GPG_COMMAND --homedir=$SECRETS_DIR_KEYS --no-permission-warning"
: ${SECRETS_EXTENSION:=".secret"}
# Inner bash :
function _function_exists {
declare -f -F "$1" > /dev/null
echo $?
}
# OS based :
function _os_based {
# Pass function name as first parameter.
# It will be invoked as os-based function with the postfix.
case "$(uname -s)" in
Darwin)
$1_osx ${@:2}
;;
Linux)
$1_linux ${@:2}
;;
# TODO: add MS Windows support.
# CYGWIN*|MINGW32*|MSYS*)
# $1_ms ${@:2}
# ;;
*)
_abort 'unsupported OS.'
;;
esac
}
# File System :
function _set_config {
# First parameter is the KEY, second is VALUE, third is filename.
# The exit status is 0 (true) if the name was found, 1 (false) if not:
local contains=$(grep -Fq "$1" $3; echo $?)
if [[ "$contains" -eq 0 ]]; then
_os_based __replace_in_file $@
elif [[ "$contains" -eq 1 ]]; then
echo "$1 = $2" >> "$3"
fi
}
function _file_has_line {
# First parameter is the KEY, second is the filename.
local contains=$(grep -qw "$1" "$2"; echo $?)
# 0 on contains, 1 for error.
echo "$contains";
}
function _delete_line {
_os_based __delete_line $@
}
function _temporary_file {
# This function creates temporary file
# which will be removed on system exit.
filename=$(_os_based __temp_file) # is not `local` on purpose.
trap "echo 'cleaning up...'; rm -f $filename;" EXIT
}
function _unique_filename {
# First parameter is base-path, second is filename,
# third is optional extension.
local n=0 result=$2
while [[ 1 ]]; do
if [[ ! -f "$1/$result" ]]; then
break
fi
n=$(( $n + 1 ))
result="$2-$n"
done
echo $result
}
# VCS :
function _check_ignore {
git check-ignore -q "$1";
echo $?
}
# Logic :
function _abort {
>&2 echo "$1 abort."
exit 1
}
function _secrets_dir_exists {
if [[ ! -d $SECRETS_DIR ]]; then
_abort "$SECRETS_DIR does not exist."
fi
}
function _user_required {
_secrets_dir_exists
local error_message="no users found. run 'git secret tell' before adding files."
if [[ ! -f "$SECRETS_DIR_KEYS_PUBRING" ]] ||
[[ ! -f "$SECRETS_DIR_KEYS_TRUSTDB" ]]; then
_abort "$error_message"
fi
local keys_exist=$($GPGLOCAL -n --list-keys --with-colon)
if [[ -z $keys_exist ]]; then
_abort "$error_message"
fi
}
function _get_raw_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")" | sed -e 's#^\./##'
}
function _get_encrypted_filename {
echo "$(dirname "$1")/$(basename "$1" "$SECRETS_EXTENSION")$SECRETS_EXTENSION" | sed -e 's#^\./##'
}
function _get_users_in_keyring {
local result=$($GPGLOCAL --list-public-keys --with-colon | sed -n 's/.*<\(.*\)>.*/\1/p')
echo "$result"
}
function _get_recepients {
local result=$($GPGLOCAL --list-public-keys --with-colon | sed -n 's/.*<\(.*\)>.*/-r\1/p')
echo "$result"
}

@ -0,0 +1,17 @@
#!/usr/bin/env bash
function __replace_in_file_linux {
sed -i.bak "s/^\($1\s*=\s*\).*\$/\1$2/" "$3"
}
function __delete_line_linux {
sed -i.bak "/$1/d" "$2"
}
function __temp_file_linux {
local filename=$(mktemp)
echo "$filename"
}

@ -0,0 +1,18 @@
#!/usr/bin/env bash
function __replace_in_file_osx {
sed -i.bak "s/^\($1[[:space:]]*=[[:space:]]*\).*\$/\1$2/" "$3"
}
function __delete_line_osx {
sed -i.bak "/$1/d" "$2"
}
function __temp_file_osx {
: "${TMPDIR:=/tmp}"
local filename=$(mktemp -t _gitsecrets_ )
echo "$filename";
}

Binary file not shown.

@ -0,0 +1,36 @@
#!/usr/bin/env bash
function add {
_user_required
local not_ignored=()
for item in $@; do
# Checking if all files in options are ignored:
if [[ ! -f "$item" ]]; then
_abort "$item is not a file."
fi
local ignored=$(_check_ignore "$item")
if [[ ! "$ignored" -eq 0 ]]; then
# collect unignored files.
not_ignored+=("$item")
fi
done
if [[ ! "${#not_ignored[@]}" -eq 0 ]]; then
# and show them all at once.
_abort "these files are not ignored: ${not_ignored[@]} ;"
fi
for item in $@; do
# adding files into system, skipping duplicates.
local already_in=$(_file_has_line "$item" "$SECRETS_DIR_PATHS_MAPPING")
if [[ "$already_in" -eq 1 ]]; then
echo "$item" >> "$SECRETS_DIR_PATHS_MAPPING"
fi
done
echo "${#@} items added."
}

@ -0,0 +1,43 @@
#!/usr/bin/env bash
function _show_help_clean {
cat <<-EOF
usage: git secret clean [-v]
removes all the hidden files.
options:
-v shows which files are deleted.
-h shows this help.
EOF
exit 0
}
function clean {
OPTIND=1
local verbose=""
while getopts "vh" opt; do
case "$opt" in
v)
verbose="v"
;;
h)
_show_help_clean
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
[[ ! -z $verbose ]] && echo && echo "cleaing:" || : # bug with custom bash on OSX
find . -name *$SECRETS_EXTENSION -type f | xargs rm -f$verbose
[[ ! -z $verbose ]] && echo || : # bug with custom bash on OSX
}

@ -0,0 +1,59 @@
#!/usr/bin/env bash
function _show_help_hide {
cat <<-EOF
usage: git secret hide [-c] [-v]
encrypts all the files added by the 'add' command.
options:
-c deletes encrypted files before creating new ones.
-v shows which files are deleted.
-h shows this help.
EOF
exit 0
}
function _optional_clean {
OPTIND=1
local clean=0
local opt_string=""
while getopts "cvh" opt; do
case "$opt" in
c) clean=1;;
h) _show_help_hide;;
v) opt_string="-v";;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
_user_required
if [[ $clean -eq 1 ]]; then
clean "$opt_string"
fi
}
function hide {
_optional_clean $@
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename $line)
local recipients=$(_get_recepients)
$GPGLOCAL --use-agent --yes --trust-model=always --encrypt $recipients -o "$encrypted_filename" "$line"
counter=$((counter+1))
done < "$SECRETS_DIR_PATHS_MAPPING"
echo "done. all $counter files are hidden."
}

@ -0,0 +1,20 @@
#!/usr/bin/env bash
function init {
if [[ -d "$SECRETS_DIR" ]]; then
_abort "already inited."
fi
local ignores=$(_check_ignore "$SECRETS_DIR"/)
if [[ ! $ignores -eq 1 ]]; then
_abort "'${SECRETS_DIR}/' is ignored."
fi
mkdir "$SECRETS_DIR" "$SECRETS_DIR_KEYS" "$SECRETS_DIR_PATHS"
touch "$SECRETS_DIR_KEYS_MAPPING" "$SECRETS_DIR_PATHS_MAPPING"
echo "'${SECRETS_DIR}/' created."
}

@ -0,0 +1,12 @@
#!/usr/bin/env bash
function killperson {
_user_required
if [[ ${#@} -eq 0 ]]; then
_abort "email is required."
fi
$GPGLOCAL --batch --yes --delete-key "$1"
}

@ -0,0 +1,14 @@
#!/usr/bin/env bash
function list {
_user_required
if [[ ! -s "$SECRETS_DIR_PATHS_MAPPING" ]]; then
exit 1
fi
while read line; do
echo "$line"
done < "$SECRETS_DIR_PATHS_MAPPING"
}

@ -0,0 +1,55 @@
#!/usr/bin/env bash
function _show_help_remove {
cat <<-EOF
usage: git secret remove [-c] <pathspec..>
removes files from git-secret's index."
options:
-c deletes existing real encrypted files.
-h shows this help.
EOF
exit 0
}
function remove {
OPTIND=1
local clean=0
while getopts "ch" opt; do
case "$opt" in
c) clean=1;;
h) _show_help_remove;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# validate if user exist:
_user_required
for item in $@; do
if [[ ! -f "$item" ]]; then
_abort "$item is not a file."
fi
_delete_line "$item" "$SECRETS_DIR_PATHS_MAPPING"
rm -f "${SECRETS_DIR_PATHS_MAPPING}.bak"
if [[ "$clean" == 1 ]]; then
local encrypted_filename=$(_get_encrypted_filename "$item")
rm -f "$encrypted_filename"
fi
done
local all=${@}
echo "removed from index."
echo "ensure that files: [$all] are now not ignored."
}

@ -0,0 +1,59 @@
#!/usr/bin/env bash
function _show_help_reveal {
cat <<-EOF
usage: git secret reveal [-d dir] [-p password]
unencrypts all the files added by the 'add' command.
options:
-d specifies --homedir option for gpg.
-p specifies password for noinput mode, adds --passphrase option for gpg.
-h shows this help.
EOF
exit 0
}
function reveal {
OPTIND=1
local homedir=""
local passphrase=""
while getopts "hd:p:" opt; do
case "$opt" in
h) _show_help_reveal;;
p) passphrase=$OPTARG;;
d) homedir=$OPTARG;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
_user_required
local counter=0
while read line; do
local encrypted_filename=$(_get_encrypted_filename "$line")
local base="$SECRETS_GPG_COMMAND --use-agent -q --decrypt"
if [[ ! -z "$homedir" ]]; then
base="$base --homedir=$homedir"
fi
if [[ ! -z "$passphrase" ]]; then
base="$base --batch --yes --passphrase $passphrase"
fi
$base -o "$line" "$encrypted_filename"
counter=$((counter+1))
done < "$SECRETS_DIR_PATHS_MAPPING"
echo "done. all $counter files are revealed."
}

@ -0,0 +1,69 @@
#!/usr/bin/env bash
function _show_help_tell {
cat <<-EOF
usage: git secret tell [-m] [-d dir] [email]
adds a person, who can access the private data.
options:
-m - takes your current 'git config user.email' as an identifier for the key.
-d - specifies '--homedir' option for the 'gpg'
-h shows this help.
EOF
exit 0
}
function tell {
_secrets_dir_exists
# A POSIX variable
# Reset in case getopts has been used previously in the shell.
OPTIND=1
local email
local homedir
while getopts "h?md:" opt; do
case "$opt" in
h) _show_help_tell;;
m) # Set email of the git current user:
email=$(git config user.email) || _abort "'git congig user.email' is not set."
;;
d) homedir=$OPTARG;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
# Custom argument-parsing:
if [[ -z $email ]]; then
# Email was not set via `-m` and is in $1:
test ! -z "$1" && email="$1"; shift || _abort "first argument must be an email address."
fi
# This file will be removed automatically:
_temporary_file
local keyfile="$filename"
if [[ -z "$homedir" ]]; then
$SECRETS_GPG_COMMAND --export -a "$email" > "$keyfile"
else
# It means that homedir is set as an extra argument via `-d`:
$SECRETS_GPG_COMMAND --no-permission-warning --homedir="$homedir" --export -a "$email" > "$keyfile"
fi
if [[ ! -s "$keyfile" ]]; then
_abort 'gpg key is empty. check your key name: `gpg --list-keys`.'
fi
# Importing public key to the local keychain:
$GPGLOCAL --import "$keyfile" > /dev/null 2>&1
echo "done. $email added as a person who knows the secret."
}

@ -0,0 +1,15 @@
#!/usr/bin/env bash
function usage {
local commands=""
local separator="|"
for com in $(compgen -A function); do
if [[ ! $com == _* ]]; then
commands+="$com$separator"
fi
done
echo "usage: git secret [${commands%?}]"
}

@ -0,0 +1,9 @@
#!/usr/bin/env bash
function whoknows {
_user_required
local keys=$(_get_users_in_keyring)
echo "$keys"
}

@ -0,0 +1,52 @@
#!/usr/bin/env bash
function _check_setup {
# Checking git and secret-plugin setup:
if [[ ! -d ".git" ]] || [[ ! -d ".git/hooks" ]]; then
_abort "repository is broken. try running 'git init' or 'git clone'."
fi
# Checking if the '.gitsecret' is not ignored:
local ignored=$(_check_ignore ".gitsecret/")
if [[ ! $ignored -eq 1 ]]; then
_abort ".gitsecret folder is ignored."
fi
# Checking gpg setup:
local secring="$SECRETS_DIR_KEYS/secring.gpg"
if [[ -f $secring ]] && [[ -s $secring ]]; then
# secring.gpg is not empty, someone has imported a private key.
_abort "it seems that someone has imported a secret key."
fi
}
function _incorrect_usage {
echo "$1"
usage
exit "$2"
}
function _init_script {
# checking for proper set-up:
_check_setup
if [[ $# == 0 ]]; then
_incorrect_usage "no input parameters provided." 126
fi
# load dependencies:
# for f in ${0%/*}/src/*/*; do [[ -f "$f" ]] && . "$f"; done
# routing the input command:
if [[ $(_function_exists "$1") == 0 ]] && [[ ! $1 == _* ]]; then
$1 "${@:2}"
else
_incorrect_usage "command $1 not found." 126
fi
}
set -e
_init_script $@

BIN
tests/.DS_Store vendored

Binary file not shown.

@ -0,0 +1,157 @@
#!/usr/bin/env bash
# This file is following a name convention defined in:
# https://github.com/sstephenson/bats
source "$SECRET_PROJECT_ROOT/src/_utils/_git_secret_tools.sh"
# Constants:
FIXTURES_DIR="$BATS_TEST_DIRNAME/fixtures"
# Folders:
TEST_SECRETS_DIR="$BATS_TMPDIR/$SECRETS_DIR"
TEST_SECRETS_DIR_PATHS_MAPPING="$BATS_TMPDIR/$SECRETS_DIR_PATHS_MAPPING"
TEST_GPG_HOMEDIR="$PWD"
# TEST_TEMP_FILE="$BATS_TMPDIR/test_temp"
# GPG-based stuff:
: ${SECRETS_GPG_COMMAND:="gpg"}
GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning"
# Personal data:
TEST_DEFAULT_USER="user1"
function test_user_password {
echo "${1}pass"
}
function test_user_email {
echo "${1}@gitsecret.io"
}
# GPG:
function _get_gpg_fingerprint_by_email {
local email="$1"
local fingerprint=$($GPGTEST --list-public-keys --with-fingerprint --with-colons | \
sed -e '/<'$email'>::scESC:/,/[A-Z0-9]\{40\}:/!d' | \
sed -e '/fpr/!d' | \
sed -n 's/fpr:::::::::\([A-Z|0-9]\{40\}\):/\1/p')
echo $fingerprint
}
function install_fixture_key {
local public_key="$BATS_TMPDIR/public-${1}.key"
local email=$(test_user_email "$1")
$SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \
--no-permission-warning --output "$public_key" \
--armor --batch --yes --export "$email" > /dev/null 2>&1
$GPGTEST --import "$public_key" > /dev/null 2>&1
rm -f "$public_key"
}
function install_fixture_full_key {
local private_key="$BATS_TMPDIR/private-${1}.key"
local email=$(test_user_email "$1")
# local fingerprint=`_get_gpg_fingerprint_by_email "$email"`
$SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \
--no-permission-warning --output "$private_key" --armor \
--yes --export-secret-key "$email" > /dev/null 2>&1
$GPGTEST --allow-secret-key-import --import "$private_key" > /dev/null 2>&1
install_fixture_key "$1"
}
function uninstall_fixture_key {
local email=$(test_user_email "$1")
$GPGTEST --batch --yes --delete-key "$email" > /dev/null 2>&1
}
function uninstall_fixture_full_key {
local email=$(test_user_email "$1")
local fingerprint=$(_get_gpg_fingerprint_by_email "$email")
$GPGTEST --batch --yes --delete-secret-keys "$fingerprint" > /dev/null 2>&1
uninstall_fixture_key "$1"
}
# Git:
function git_set_config_email {
git config --local user.email "$1"
}
function git_restore_default_email {
git config --local user.email "$1"
}
function remove_git_repository {
rm -rf ".git"
}
# Git Secret:
function set_state_git {
git init > /dev/null 2>&1
}
function set_state_secret_init {
git secret init > /dev/null 2>&1
}
function set_state_secret_tell {
local email=$(test_user_email $1)
git secret tell -d "$TEST_GPG_HOMEDIR" "$email" > /dev/null 2>&1
}
function set_state_secret_add {
local filename="$1"
local content="$2"
echo "$content" > "$filename"
echo "$filename" >> ".gitignore"
git secret add "$filename" > /dev/null 2>&1
}
function set_state_secret_hide {
git secret hide > /dev/null 2>&1
}
function unset_current_state {
# states order:
# git, secret_init, secret_tell, secret_add, secret_hide
# unsets `secret_hide`
# removes .secret files:
git secret clean > /dev/null 2>&1
# unsets `secret_add`, `secret_tell` and `secret_init`
rm -rf "$SECRETS_DIR"
rm -rf ".gitignore"
# unsets `git` state
remove_git_repository
# removes gpg homedir:
rm -f "pubring.gpg" "pubring.gpg~" "secring.gpg" "trustdb.gpg" "random_seed"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,78 @@
#!/usr/bin/env bats
load _test_base
function setup {
install_fixture_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
}
function teardown {
uninstall_fixture_key "$TEST_DEFAULT_USER"
unset_current_state
}
@test "run 'add' for unignored file" {
local TEST_FILE='test_file'
touch "$TEST_FILE"
echo "content" > "$TEST_FILE"
run git secret add "$TEST_FILE"
rm -f "$TEST_FILE"
[ "$status" -eq 1 ]
}
@test "run 'add' normally" {
local filename="local_file"
echo "content" > "$filename"
echo "$filename" > ".gitignore"
run git secret add "$filename"
rm -f "$filename" ".gitignore"
[ "$status" -eq 0 ]
local files_list=$(cat "$SECRETS_DIR_PATHS_MAPPING")
[ "$files_list" = "$filename" ]
}
@test "run 'add' twice for one file" {
local filename="local_file"
echo "content" > "$filename"
echo "$filename" > ".gitignore"
run git secret add "$filename"
run git secret add "$filename"
rm -f "$filename" ".gitignore"
[ "$status" -eq 0 ]
[ "$output" = "1 items added." ]
local files_list=`cat "$SECRETS_DIR_PATHS_MAPPING"`
[ "$files_list" = "$filename" ]
}
@test "run 'add' for multiple files" {
local filename1="local_file1"
echo "content1" > "$filename1"
echo "$filename1" > ".gitignore"
local filename2="local_file2"
echo "content2" > "$filename2"
echo "$filename2" >> ".gitignore"
run git secret add "$filename1" "$filename2"
rm -f "$filename1" "$filename2" ".gitignore"
[ "$status" -eq 0 ]
[ "$output" = "2 items added." ]
}

@ -0,0 +1,49 @@
#!/usr/bin/env bats
load _test_base
FILE_TO_HIDE="file_to_hide"
FILE_CONTENTS="hidden content юникод"
function setup {
install_fixture_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
set_state_secret_add "$FILE_TO_HIDE" "$FILE_CONTENTS"
}
function teardown {
uninstall_fixture_key $TEST_DEFAULT_USER
unset_current_state
rm -f "$FILE_TO_HIDE"
}
@test "run 'hide' normally" {
run git secret hide
[ "$status" -eq 0 ]
[ "$output" = "done. all 1 files are hidden." ]
}
@test "run 'hide' with params" {
run git secret hide -v -c
[ "$status" -eq 0 ]
}
@test "run 'hide' for multiple users" {
local new_user="user2"
install_fixture_key "$new_user"
set_state_secret_tell "$new_user"
run git secret hide
[ "$status" -eq 0 ]
[ "$output" = "done. all 1 files are hidden." ]
}

@ -0,0 +1,37 @@
#!/usr/bin/env bats
load _test_base
function setup {
set_state_git
}
function teardown {
unset_current_state
}
@test "run 'init' without .git" {
remove_git_repository
run git secret init
[ "$status" -eq 1 ]
[ "$output" = "repository is broken. try running 'git init' or 'git clone'. abort." ]
}
@test "run 'init' normally" {
run git secret init
[ "$status" -eq 0 ]
}
@test "run 'init' with '.gitsecret' already inited" {
mkdir "$SECRETS_DIR"
run git secret init
[ "$output" = "already inited. abort." ]
[ "$status" -eq 1 ]
}

@ -0,0 +1,33 @@
#!/usr/bin/env bats
load _test_base
function setup {
install_fixture_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
# init_git_repository
# git_secret_init
# git_secret_tell_test
}
function teardown {
uninstall_fixture_key "$TEST_DEFAULT_USER"
unset_current_state
}
@test "run 'killperson' without arguments" {
run git secret killperson
[ "$status" -eq 1 ]
}
@test "run 'killperson' normally" {
run git secret killperson "$TEST_DEFAULT_USER"
[ "$status" -eq 0 ]
}

@ -0,0 +1,39 @@
#!/usr/bin/env bats
load _test_base
FILE_TO_HIDE="file_to_hide"
FILE_CONTENTS="hidden content юникод"
function setup {
install_fixture_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
set_state_secret_add "$FILE_TO_HIDE" "$FILE_CONTENTS"
}
function teardown {
uninstall_fixture_key $TEST_DEFAULT_USER
unset_current_state
rm -f "$FILE_TO_HIDE"
}
@test "run 'list' normally" {
run git secret list
[ "$status" -eq 0 ]
[ "$output" = "$FILE_TO_HIDE" ]
}
@test "run 'list' on empty repo" {
git secret remove "$FILE_TO_HIDE"
run git secret list
[ "$status" -eq 1 ]
}

@ -0,0 +1,25 @@
#!/usr/bin/env bats
load _test_base
function setup {
set_state_git
}
function teardown {
unset_current_state
}
@test "run 'git secret' without command" {
run git secret
[ "$status" -eq 126 ]
}
@test "run 'git secret' with bad command" {
run git secret notacommand
[ "$status" -eq 126 ]
}

@ -0,0 +1,59 @@
#!/usr/bin/env bats
load _test_base
FIRST_FILE="file_to_hide1"
SECOND_FILE="file_to_hide2"
function setup {
install_fixture_full_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
set_state_secret_add "$FIRST_FILE" "$FIRST_FILE"
set_state_secret_add "$SECOND_FILE" "$SECOND_FILE"
}
function teardown {
uninstall_fixture_full_key "$TEST_DEFAULT_USER"
unset_current_state
rm -f "$FIRST_FILE" "$SECOND_FILE"
}
@test "run 'remove' normally" {
git secret hide
run git secret remove "$SECOND_FILE"
[ "$status" -eq 0 ]
local mapping_contains=$(grep "$SECOND_FILE" "$SECRETS_DIR_PATHS_MAPPING"; echo $?)
[ "$mapping_contains" -eq 1 ]
local first_enctypted_file=$(_get_encrypted_filename $FIRST_FILE)
local second_enctypted_file=$(_get_encrypted_filename $SECOND_FILE)
[ -f "$first_enctypted_file" ]
[ -f "$second_enctypted_file" ]
}
@test "run 'remove -c'" {
git secret hide
run git secret remove -c "$SECOND_FILE"
echo "$output"
[ "$status" -eq 0 ]
local mapping_contains=$(grep "$SECOND_FILE" "$SECRETS_DIR_PATHS_MAPPING"; echo $?)
[ "$mapping_contains" -eq 1 ]
local first_enctypted_file=$(_get_encrypted_filename $FIRST_FILE)
local second_enctypted_file=$(_get_encrypted_filename $SECOND_FILE)
[ -f "$first_enctypted_file" ]
[ ! -f "$second_enctypted_file" ]
}

@ -0,0 +1,81 @@
#!/usr/bin/env bats
load _test_base
FILE_TO_HIDE="file_to_hide"
FILE_CONTENTS="hidden content юникод"
function setup {
install_fixture_full_key "$TEST_DEFAULT_USER"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
set_state_secret_add "$FILE_TO_HIDE" "$FILE_CONTENTS"
set_state_secret_hide
}
function teardown {
uninstall_fixture_full_key "$TEST_DEFAULT_USER"
unset_current_state
rm -f "$FILE_TO_HIDE"
}
@test "run 'reveal' with password argument" {
cp "$FILE_TO_HIDE" "${FILE_TO_HIDE}2"
rm -f "$FILE_TO_HIDE"
local password=$(test_user_password "$TEST_DEFAULT_USER")
run git secret reveal -d "$TEST_GPG_HOMEDIR" -p "$password"
[ "$status" -eq 0 ]
[ -f "$FILE_TO_HIDE" ]
cmp --silent "$FILE_TO_HIDE" "${FILE_TO_HIDE}2"
rm -f "${FILE_TO_HIDE}2"
}
@test "run 'reveal' with wrong password" {
rm -f "$FILE_TO_HIDE"
run git secret reveal -d "$TEST_GPG_HOMEDIR" -p "WRONG"
[ "$status" -eq 2 ]
[ ! -f "$FILE_TO_HIDE" ]
}
@test "run 'reveal' for attacker" {
rm -f "$FILE_TO_HIDE"
local attacker="attacker1"
install_fixture_full_key "$attacker"
local password=$(test_user_password "$attacker")
run git secret reveal -d "$TEST_GPG_HOMEDIR" -p "$password"
[ "$status" -eq 2 ]
[ ! -f "$FILE_TO_HIDE" ]
uninstall_fixture_full_key "$attacker"
}
@test "run 'reveal' for multiple users" {
local new_user="user2"
install_fixture_full_key "$new_user"
set_state_secret_tell "$new_user"
set_state_secret_hide
uninstall_fixture_full_key "$TEST_DEFAULT_USER"
local password=$(test_user_password "$new_user")
run git secret reveal -d "$TEST_GPG_HOMEDIR" -p "$password"
[ "$status" -eq 0 ]
[ -f "$FILE_TO_HIDE" ]
}

@ -0,0 +1,76 @@
#!/usr/bin/env bats
load _test_base
function setup {
install_fixture_key $TEST_DEFAULT_USER
set_state_git
set_state_secret_init
}
function teardown {
uninstall_fixture_key "$TEST_DEFAULT_USER"
unset_current_state
}
function git_secret_tell_test {
git secret tell -d "$TEST_GPG_HOMEDIR" "$TEST_DEFAULT_USER"
}
@test "fail on no users" {
run _user_required
[ "$status" -eq 1 ]
}
@test "run 'tell' with secret-key imported" {
local private_key="$SECRETS_DIR_KEYS/secring.gpg"
echo "private key" > "$private_key"
[ -s "$private_key" ]
run git_secret_tell_test
[ "$status" -eq 1 ]
}
@test "run 'tell' without '.gitsecret'" {
rm -rf "$SECRETS_DIR"
run git_secret_tell_test
[ "$status" -eq 1 ]
}
@test "run 'tell' without arguments" {
run git secret tell
[ "$status" -eq 1 ]
}
@test "run 'tell' normally" {
run git_secret_tell_test
[ "$status" -eq 0 ]
run _user_required
[ "$status" -eq 0 ]
}
@test "run 'tell -m'" {
email=$(test_user_email $TEST_DEFAULT_USER)
git_set_config_email "$email"
run git secret tell -d "$TEST_GPG_HOMEDIR" -m
[ "$status" -eq 0 ]
}
@test "run 'tell -m' with empty email" {
git_set_config_email ""
run git secret tell -d "$TEST_GPG_HOMEDIR" -m
[ "$status" -eq 1 ]
}

@ -0,0 +1,34 @@
#!/usr/bin/env bats
load _test_base
function setup {
set_state_git
}
function teardown {
unset_current_state
}
@test "run 'usage'" {
run git secret usage
[ "$status" -eq 0 ]
}
@test "run 'usage' without '.git/'" {
remove_git_repository
run git secret usage
[ "$status" -eq 1 ]
}
@test "run 'usage' with ignored '.gitsecret/'" {
echo ".gitsecret/" >> ".gitignore"
run git secret usage
[ "$status" -eq 1 ]
}

@ -0,0 +1,28 @@
#!/usr/bin/env bats
load _test_base
function setup {
install_fixture_key "$TEST_DEFAULT_USER"
install_fixture_key "user2"
set_state_git
set_state_secret_init
set_state_secret_tell "$TEST_DEFAULT_USER"
set_state_secret_tell "user2"
}
function teardown {
uninstall_fixture_key $TEST_DEFAULT_USER
unset_current_state
rm -f "$FILE_TO_HIDE"
}
@test "run 'whoknows' normally" {
run git secret whoknows
[ "$status" -eq 0 ]
}

@ -0,0 +1,9 @@
#!/bin/sh
set -e
# Run tests:
make test
# Build new manuals:
make build-man

1
vendor/bats vendored

@ -0,0 +1 @@
Subproject commit 955309ab943ea157ded0c402df98b160bb45ff92
Loading…
Cancel
Save