Skip to content

Commit

Permalink
Add rmdir command.
Browse files Browse the repository at this point in the history
Fixed bug that misjudged applet arguments as mimixbox arguments.
  • Loading branch information
nao1215 committed Nov 18, 2021
1 parent 7b350b8 commit 883e99c
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 5 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Changelog
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.4.0] - 2021-11-18
## [0.5.1] - 2021-11-18
### Added
- rm command.
- rmdir command.
### Changed
- The library that was open to the public(pkg) to the internal library.
### Fixed
- Bug that misjudged applet arguments as mimixbox arguments.
## [0.3.0] - 2021-11-17
### Added
- touch command.
Expand Down
7 changes: 5 additions & 2 deletions cmd/mimixbox/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type options struct {

var osExit = os.Exit

const version = "0.4.1"
const version = "0.5.1"

const (
ExitSuccess int = iota // 0
Expand Down Expand Up @@ -97,7 +97,10 @@ func main() {
func handleMimixBoxOptionsIfNeeded(parser *flags.Parser, opts *options) {
mimixBoxPath := os.Args[0]

if !hasInstallOption() && !hasRemoveOption() && hasAppletName() {
// As a temporary workaround for the bug, if the Applet name is included in the argument,
// it is considered not to be an argument of mimixbox.
// The directory with the same name as an applet can no longer be an installation directory.
if hasAppletName() {
return
}

Expand Down
2 changes: 1 addition & 1 deletion docs/man/mimixbox/en/mimixbox.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ commands.

# Command(applet)list
**Common unix commands(applets)**
cat, chroot, echo, false, ischroot, mkdir, mv, rm, touch, true, which
cat, chroot, echo, false, ischroot, mkdir, mv, rm, rmdir, touch, true, which

**MimixBox Original commands(applets)**
fakemovie, ghrdc, mbsh(sh), path, serial
Expand Down
2 changes: 1 addition & 1 deletion docs/man/mimixbox/ja/mimixbox.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Coreutils等が提供する基本的な内容から実験的なコマンドま

# コマンド(applet)一覧
**一般的なUnixコマンド(applet)**
cat, chroot, echo, false, ischroot, mkdir, mv, rm, touch, true, which
cat, chroot, echo, false, ischroot, mkdir, mv, rm, rmdir, touch, true, which

**MimixBoxオリジナルコマンド(applet)**
fakemovie, ghrdc, mbsh(sh), path, serial
Expand Down
2 changes: 2 additions & 0 deletions internal/applets/applet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"mimixbox/internal/applets/fileutils/mkdir"
"mimixbox/internal/applets/fileutils/mv"
"mimixbox/internal/applets/fileutils/rm"
"mimixbox/internal/applets/fileutils/rmdir"
"mimixbox/internal/applets/fileutils/touch"
"mimixbox/internal/applets/jokeutils/fakemovie"
"mimixbox/internal/applets/shellutils/chroot"
Expand Down Expand Up @@ -63,6 +64,7 @@ func init() {
"mv": {mv.Run, "Rename SOURCE to DESTINATION, or move SOURCE(s) to DIRECTORY"},
"path": {path.Run, "Manipulate filename path"},
"rm": {rm.Run, "Remove file(s) or directory(s)"},
"rmdir": {rmdir.Run, "Remove directory"},
"serial": {serial.Run, "Rename the file to the name with a serial number"},
"sh": {mbsh.Run, "Mimix Box Shell"},
"touch": {touch.Run, "Update the access and modification times of each FILE to the current time"},
Expand Down
154 changes: 154 additions & 0 deletions internal/applets/fileutils/rmdir/rmdir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//
// mimixbox/internal/applets/fileutils/rmdir/rmdir.go
//
// Copyright 2021 Naohiro CHIKAMATSU
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rmdir

import (
"errors"
"fmt"
mb "mimixbox/internal/lib"
"os"
"path/filepath"
"strings"

"github.com/jessevdk/go-flags"
)

const cmdName string = "rmdir"

const version = "1.0.0"

var osExit = os.Exit

// Exit code
const (
ExitSuccess int = iota // 0
ExitFailuer
)

type options struct {
Ignore bool `short:"i" long:"ignore-fail-on-non-empty" description:"Ignore the error if the directory is not empty"`
Parents bool `short:"p" long:"parents" description:"Remove DIRECTORY and its parents"`
Version bool `short:"v" long:"version" description:"Show rmdir command version"`
}

func Run() (int, error) {
var opts options
var args []string
var err error
var status int

if args, err = parseArgs(&opts); err != nil {
return ExitFailuer, nil
}

// Coremb will continue to delete files as much as possible.
// MimixBox stops processing if an error occurs even once.
for _, path := range args {
if status, err := rmdir(path, opts); err != nil {
return status, err
}
}
return status, nil
}

func rmdir(path string, opts options) (int, error) {
if err := validBeforeRemove(path); err != nil {
return ExitFailuer, err
}

var target string
if opts.Parents {
target = ancestorDir(path)
} else {
target = path
}

_, files, err := mb.Walk(target)
if err != nil {
return ExitFailuer, err
}
if len(files) != 0 {
if opts.Ignore {
return ExitSuccess, nil
}
return ExitFailuer, errors.New("Can't remove " + path + ": It's not empty directory")
}

// The contents of the directory are empty. Delete directories at once
if err := os.RemoveAll(target); err != nil {
return ExitFailuer, err
}
return ExitSuccess, nil
}

func ancestorDir(path string) string {
dirs := strings.Split(path, string(filepath.Separator))
return dirs[0]
}

func validBeforeRemove(path string) error {
if !mb.Exists(path) {
return errors.New("can't remove " + path + ": No such file or directory exists")
}

if mb.IsFile(path) {
return errors.New("can't remove " + path + ": It's not directory")
}

return nil
}

func parseArgs(opts *options) ([]string, error) {
p := initParser(opts)

args, err := p.Parse()
if err != nil {
return nil, err
}

if opts.Version {
showVersion()
osExit(ExitSuccess)
}

if !isValidArgNr(args) {
showHelp(p)
osExit(ExitFailuer)
}
return args, nil
}

func initParser(opts *options) *flags.Parser {
parser := flags.NewParser(opts, flags.Default)
parser.Name = cmdName
parser.Usage = "[OPTIONS] PATH"

return parser
}

func isValidArgNr(args []string) bool {
return len(args) >= 1
}

func showVersion() {
description := cmdName + " version " + version + " (under Apache License verison 2.0)\n"
fmt.Print(description)
}

func showHelp(p *flags.Parser) {
p.WriteHelp(os.Stdout)
}

0 comments on commit 883e99c

Please sign in to comment.