Skip to content

Commit

Permalink
v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
codeclown committed Jun 5, 2020
0 parents commit 348017c
Show file tree
Hide file tree
Showing 31 changed files with 2,627 additions and 0 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Build
on: [push, pull_request]
jobs:
#
# Build binaries
#
build_linux:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Test
run: make test
- name: Build
run: OUT=cronedit-linux make build
- name: Store binary
uses: actions/upload-artifact@v2
with:
name: cronedit-linux
path: bin/cronedit-linux
build_macos:
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Test
run: make test
- name: Build
run: OUT=cronedit-macos make build
- name: Store binary
uses: actions/upload-artifact@v2
with:
name: cronedit-macos
path: bin/cronedit-macos
#
# Prepare a release if current commit is tagged
#
create_release:
runs-on: ubuntu-18.04
if: startsWith(github.ref, 'refs/tags/v')
needs: [build_linux, build_macos]
steps:
# Draft
- name: Create release draft
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: true
# cronedit-linux
- name: Download cronedit-linux
uses: actions/download-artifact@v2
with:
name: cronedit-linux
path: .
- name: Upload cronedit-linux
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./cronedit-linux
asset_name: cronedit-linux
asset_content_type: application/octet-stream
# cronedit-macos
- name: Download cronedit-macos
uses: actions/download-artifact@v2
with:
name: cronedit-macos
path: .
- name: Upload cronedit-macos
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./cronedit-macos
asset_name: cronedit-macos
asset_content_type: application/octet-stream
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bin
.filesystem_test.tmp
51 changes: 51 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Development

Cronedit is written in C++/C and without external dependencies. Supported platforms are debian and MacOS.

## How to develop locally

Clone the repository:

```bash
git clone [email protected]:codeclown/cronedit.git
cd cronedit/
```

Run tests:

```bash
make test
```

Build binaries (written into `bin/`):

```bash
make build
```

Run the build:

```bash
./bin/cronedit lib/sample.txt
```

## Release process

### CI builds

For each commit and pull request, GitHub Actions is used to automatically build binaries on:

- Ubuntu 18.04
- MacOS 10.15 (Catalina)

The resulting binaries are uploaded as artifacts into the respective GitHub workflow.

See [`.github/workflows/build.yml`](.github/workflows/build.yml).

### Making a release

1. Bump the version in [`lib/version.h`](lib/version.h), e.g. `#define CRONEDIT_VERSION "0.1.1"`
2. Add a git tag, e.g. `git tag v0.1.1`
3. Push with tags `git push --tags`
4. GitHub action detects the new tag and creates a draft release with attached binaries. Review and publish it here:
https://github.com/codeclown/cronedit/releases
24 changes: 24 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Copyright (c) 2020, Martti Laine
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL A COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
GXX ?= g++
OUT ?= cronedit
libs = lib/parser.cpp lib/exec.cpp lib/filesystem.cpp lib/state.cpp lib/render.cpp lib/terminal.cpp lib/stringify.cpp lib/args.cpp

build:
mkdir -p bin && $(GXX) $(libs) lib/cronedit.cpp -o bin/$(OUT)

test:
mkdir -p bin && $(GXX) $(libs) lib/args_test.cpp -o bin/args_test && ./bin/args_test
mkdir -p bin && $(GXX) $(libs) lib/filesystem_test.cpp -o bin/filesystem_test && ./bin/filesystem_test
mkdir -p bin && $(GXX) $(libs) lib/parser_test.cpp -o bin/parser_test && ./bin/parser_test
mkdir -p bin && $(GXX) $(libs) lib/state_test.cpp -o bin/state_test && ./bin/state_test
mkdir -p bin && $(GXX) $(libs) lib/stringify_test.cpp -o bin/stringify_test && ./bin/stringify_test
mkdir -p bin && $(GXX) $(libs) lib/render_test.cpp -o bin/render_test && ./bin/render_test
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# cronedit

> an interactive command line editor for crontab
## This project is in BETA!

**Note that this is an early version of cronedit. Versions 0.X.X should be considered beta versions and probably not suited for use in critical production environments. Recommended for use only in testing environments.**

If you want to be extra safe, or just play around, copy crontab contents into a file and edit that file with cronedit:

```bash
# copy crontab contents to .txt file
crontab -l > foobar.txt
# edit that file via cronedit
./cronedit foobar.txt
```

## Usage

```shell
$ cronedit --help
cronedit v0.1.0

Usage:
./bin/cronedit
./bin/cronedit <file>

Arguments:
file If given, this file is read and written to
instead of modifying crontab directly via
the 'crontab' command

Options:
-h, --help Show this help message
-v, --version Show cronedit version

Information about backups:
Upon saving changes, previous crontab version is backed up
into folder '$HOME/.cronedit'.

Source:
This program is open source and available at:
https://github.com/codeclown/cronedit

```

## Development

See [DEVELOPMENT.md](DEVELOPMENT.md).

## License

Released under 3-clause BSD License, see [LICENSE.md](LICENSE.md).
59 changes: 59 additions & 0 deletions lib/args.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <string>
#include <vector>
#include "args.h"

Args parse_args(int argc, char* argv[]) {
Args args;
args.show_usage = false;
args.show_version = false;
args.filename = "";

std::vector<std::string> filenames;

for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "--help" || arg == "-h") {
args.show_usage = true;
return args;
}
if (arg == "--version" || arg == "-v") {
args.show_version = true;
return args;
}
filenames.push_back(arg);
}

if (filenames.size() > 1) {
args.show_usage = true;
} else if (filenames.size() > 1) {
args.show_usage = true;
} else if (filenames.size() == 1) {
args.filename = filenames[0];
}

return args;

// bool show_usage = false;
// if (argc >= 2) {
// for (int i = 1; i < argc; i++) {
// std::string arg = argv[i];
// if (arg == "--help" || arg == "-h") {
// show_usage = true;
// break;
// }
// }
// }
// if (show_usage) {
// print_usage(argv[0]);
// exit(0);
// } else if (argc > 2) {
// print_usage(argv[0]);
// exit(1);
// }
// std::string file_arg = "";
// if (argc == 2) {
// file_arg = argv[1];
// }

// return args;
}
12 changes: 12 additions & 0 deletions lib/args.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef ARGS_H
#define ARGS_H

struct Args {
bool show_usage;
bool show_version;
std::string filename;
};

Args parse_args(int argc, char* argv[]);

#endif
52 changes: 52 additions & 0 deletions lib/args_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <sstream>
#include <iostream>
#include <string>
#include <assert.h>
#include "args.h"

int main()
{
char *argv1[1] = { (char*)"./bin/cronedit" };
Args args1 = parse_args(1, argv1);
assert(args1.show_usage == false);
assert(args1.show_version == false);
assert(args1.filename == "");

char *argv2[2] = { (char*)"./bin/cronedit", (char*)"-h" };
Args args2 = parse_args(2, argv2);
assert(args2.show_usage == true);
assert(args2.show_version == false);
assert(args2.filename == "");

char *argv3[2] = { (char*)"./bin/cronedit", (char*)"--help" };
Args args3 = parse_args(2, argv3);
assert(args3.show_usage == true);
assert(args3.show_version == false);
assert(args3.filename == "");

char *argv4[2] = { (char*)"./bin/cronedit", (char*)"-v" };
Args args4 = parse_args(2, argv4);
assert(args4.show_usage == false);
assert(args4.show_version == true);
assert(args4.filename == "");

char *argv5[2] = { (char*)"./bin/cronedit", (char*)"--version" };
Args args5 = parse_args(2, argv5);
assert(args5.show_usage == false);
assert(args5.show_version == true);
assert(args5.filename == "");

char *argv6[2] = { (char*)"./bin/cronedit", (char*)"foobar" };
Args args6 = parse_args(2, argv6);
assert(args6.show_usage == false);
assert(args6.show_version == false);
assert(args6.filename == "foobar");

char *argv7[3] = { (char*)"./bin/cronedit", (char*)"foobar", (char*)"lorem" };
Args args7 = parse_args(3, argv7);
assert(args7.show_usage == true);
assert(args7.show_version == false);
assert(args7.filename == "");

std::cout << "PASS" << std::endl;
}
Loading

0 comments on commit 348017c

Please sign in to comment.