~hrbrmstr/cloc

bd517e321beb2b78cf28d02fc3204541d696ff87 — boB Rudis 6 years ago ca0798a
purl & pkg
M DESCRIPTION => DESCRIPTION +4 -0
@@ 15,6 15,10 @@ SystemRequirements: perl
Copyright: file inst/COPYRIGHTS
Imports:
    rstudioapi (>= 0.5),
    rprojroot,
    DT,
    knitr,
    htmltools,
    git2r,
    utils, 
    dplyr,

M NAMESPACE => NAMESPACE +7 -0
@@ 7,12 7,19 @@ export(cloc_cran)
export(cloc_git)
export(cloc_help)
export(cloc_os)
export(cloc_pkg)
export(cloc_remove_comments)
export(cloc_reognized_languages)
export(cloc_version)
import(rstudioapi)
importFrom(DT,datatable)
importFrom(DT,formatPercentage)
importFrom(git2r,clone)
importFrom(htmltools,HTML)
importFrom(htmltools,html_print)
importFrom(knitr,purl)
importFrom(processx,run)
importFrom(rprojroot,find_package_root_file)
importFrom(utils,contrib.url)
importFrom(utils,download.file)
importFrom(utils,download.packages)

M R/cloc-package.r => R/cloc-package.r +4 -0
@@ 54,6 54,10 @@
#' @name cloc-package
#' @docType package
#' @author Bob Rudis (bob@@rud.is)
#' @importFrom DT datatable formatPercentage
#' @importFrom htmltools html_print HTML
#' @importFrom knitr purl
#' @importFrom rprojroot find_package_root_file
#' @import rstudioapi
#' @importFrom git2r clone
#' @importFrom processx run

A R/cloc-pkg.R => R/cloc-pkg.R +39 -0
@@ 0,0 1,39 @@
#' @keywords internal
cloc_pkg_addin <- function() {

  ctx <- rstudioapi::getActiveDocumentContext()

  if (!is.null(ctx)) {

    pkg_root <- rprojroot::find_package_root_file(path = ".")

    res <- cloc::cloc_pkg(pkg_root)
    res <- res[,-1] # we know what pkg we're in

    DT::datatable(
      data = res,
      options = list(pageLength = 20),
      colnames = c(
        "Lang",
        "# Files", "(%)",
        "LoC", "(%)",
        "Blank lines", "(%)",
        "# Lines", "(%)"
      ),
      caption = sprintf("Code Metrics For %s", basename(pkg_root)),
      style = "default"
    ) -> cloc_dt

    cloc_dt <- DT::formatPercentage(cloc_dt, 'file_count_pct', 2)
    cloc_dt <- DT::formatPercentage(cloc_dt, 'loc_pct', 2)
    cloc_dt <- DT::formatPercentage(cloc_dt, 'blank_line_pct', 2)
    cloc_dt <- DT::formatPercentage(cloc_dt, 'comment_line_pct', 2)

    htmltools::html_print(cloc_dt)

    print(res)

  }

}


A R/clock-pkg-src.R => R/clock-pkg-src.R +103 -0
@@ 0,0 1,103 @@
#' Count lines of code, comments and whitespace in a package
#'
#' Think of this as [cloc()] with saner defaults for packages. Skips common
#' IDE tempdirs, `.git`, `inst`, `man`.
#'
#' @md
#' @param source file, directory or archive to read from (can be a valid URL)
#' @param extract_with passed into `cloc` command line. This option is only
#'        needed if cloc is unable to figure out how to extract the contents of
#'        the input file(s) by itself.
#' @return tibble
#' @export
#' @examples
#' # by dir
#' cloc(system.file("extdata", package="cloc"))
#'
#' # by file
#' cloc(system.file("extdata", "App.java", package="cloc"))
#'
#' # requires a network connection therefore is set for you to run it manually
#' \dontrun{
#' # from a url
#' cloc("https://rud.is/dl/cloc-1.74.tar.gz")
#' }
cloc_pkg <- function(source = ".", extract_with = NULL) {

  perl <- find_perl()

  tis_url <- is_url(source)

  if (tis_url) { # download the source if a URL was specified
    tdir <- tempdir()
    utils::download.file(source, file.path(tdir, basename(source)), method = "curl", quiet = TRUE)
    source <- file.path(tdir, basename(source))
    on.exit(unlink(source), add = TRUE)
  }

  source <- path.expand(source)

  stopifnot(file.exists(source))

  # make the command line

  sprintf(
    "%s %s --exclude-ext=yml,md,Rproj --exclude-dir=.Rproj,.Rproj.user,.git,inst,man,docs,tools --quiet --csv %s",
    perl,
    system.file("bin/cloc.pl", package = "cloc"),
    source
  ) -> cmd

  # tack on the "--extract-with" value (if specified)
  if (!is.null(extract_with)) cmd <- sprintf('%s --extract-with="%s"', cmd, extract_with)

  # run the perl script
  dat <- system(cmd, intern = TRUE)

  # nothing to count
  if (length(dat) == 0) {
    return(
      data.frame(
        source = basename(source),
        language = NA_character_,
        file_count = 0,
        file_count_pct = 0,
        loc = 0,
        loc_pct = 0,
        blank_lines = 0,
        blank_line_pct = 0,
        comment_lines = 0,
        comment_line_pct = 0,
        stringsAsFactors = FALSE
      )
    )
  }

  # read in the output from the perl script
  fil <- read.table(
    text = paste(utils::tail(dat, -2), sep = "", collapse = "\n"),
    col.names = c("file_count", "language", "blank_lines", "comment_lines", "loc"),
    sep = ",", comment.char = "", stringsAsFactors = FALSE
  )

  # calculate percentages
  fil$source <- basename(source)
  fil$file_count_pct <- fil$file_count / sum(fil$file_count)
  fil$blank_line_pct <- fil$blank_lines / sum(fil$blank_lines)
  fil$comment_line_pct <- fil$comment_lines / sum(fil$comment_lines)
  fil$loc_pct <- fil$loc / sum(fil$loc)

  # reorganize columns
  fil <- fil[, c(
    "source", "language",
    "file_count", "file_count_pct",
    "loc", "loc_pct",
    "blank_lines", "blank_line_pct",
    "comment_lines", "comment_line_pct"
  )]

  class(fil) <- c("tbl_df", "tbl", "data.frame")

  fil

}

A R/purl-rmd.R => R/purl-rmd.R +37 -0
@@ 0,0 1,37 @@

#' @keywords internal
purl_rmd_addin <- function() {

  ctx <- rstudioapi::getActiveDocumentContext()

  if (!is.null(ctx)) {

    if (is_rmd_file(ctx$path)) {

      x <- basename(ctx$path)
      x <- tools::file_path_sans_ext(x)

      tf1 <- tempfile(pattern = x, fileext = ".Rmd")
      on.exit(unlink(tf1), add = TRUE)

      tf2 <- tempfile(pattern = x, fileext = ".R")

      cat(ctx$contents, file = tf1, sep = "\n")

      knitr::purl(tf1, output = tf2)

      navigateToFile(tf2, line = -1L, column = -1L)

      message(
        sprintf(
          "Temporary file generated is in [%s]", tf2
        )
      )

    } else {
      stop("Can only style .R and .Rmd files.", call. = FALSE)
    }

  }

}

M R/strip-rmd.R => R/strip-rmd.R +1 -1
@@ 1,5 1,5 @@
#' @keywords internal
strip_rmd <- function() {
strip_rmd_addin <- function() {

  ctx <- rstudioapi::getActiveDocumentContext()


M inst/rstudio/addins.dcf => inst/rstudio/addins.dcf +12 -2
@@ 1,4 1,14 @@
Name: Strip Rmd
Description: Removes everything but code blocks from the active Rmd file
Binding: strip_rmd
Description: Removes everything but code blocks from the active Rmd file (uses cloc)
Binding: strip_rmd_addin
Interactive: false

Name: purl Rmd
Description: Removes everything but code blocks from the active Rmd file (uses knitr::purl)
Binding: purl_rmd_addin
Interactive: false

Name: cloc Package
Description: Run cloc on current package and present results
Binding: cloc_pkg_addin
Interactive: false

A man/cloc_pkg.Rd => man/cloc_pkg.Rd +35 -0
@@ 0,0 1,35 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/clock-pkg-src.R
\name{cloc_pkg}
\alias{cloc_pkg}
\title{Count lines of code, comments and whitespace in a package}
\usage{
cloc_pkg(source = ".", extract_with = NULL)
}
\arguments{
\item{source}{file, directory or archive to read from (can be a valid URL)}

\item{extract_with}{passed into \code{cloc} command line. This option is only
needed if cloc is unable to figure out how to extract the contents of
the input file(s) by itself.}
}
\value{
tibble
}
\description{
Think of this as \code{\link[=cloc]{cloc()}} with saner defaults for packages. Skips common
IDE tempdirs, \code{.git}, \code{inst}, \code{man}.
}
\examples{
# by dir
cloc(system.file("extdata", package="cloc"))

# by file
cloc(system.file("extdata", "App.java", package="cloc"))

# requires a network connection therefore is set for you to run it manually
\dontrun{
# from a url
cloc("https://rud.is/dl/cloc-1.74.tar.gz")
}
}