<commit_before>/*
Copyright 2016 Google Inc. All Rights Reserved.

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.
*/

// Buildifier, a tool to parse and format BUILD files.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"

	"github.com/bazelbuild/buildtools/build"
	"github.com/bazelbuild/buildtools/differ"
	"github.com/bazelbuild/buildtools/tables"
)

var buildifierVersion = "redacted"
var buildScmRevision = "redacted"

var (
	// Undocumented; for debugging.
	showlog = flag.Bool("showlog", false, "show log in check mode")

	vflag         = flag.Bool("v", false, "print verbose information on standard error")
	dflag         = flag.Bool("d", false, "alias for -mode=diff")
	mode          = flag.String("mode", "", "formatting mode: check, diff, or fix (default fix)")
	path          = flag.String("path", "", "assume BUILD file has this path relative to the workspace directory")
	tablesPath    = flag.String("tables", "", "path to JSON file with custom table definitions which will replace the built-in tables")
	addTablesPath = flag.String("add_tables", "", "path to JSON file with custom table definitions which will be merged with the built-in tables")
	version       = flag.Bool("version", false, "Print the version of buildifier")

	// Debug flags passed through to rewrite.go
	allowSort = stringList("allowsort", "additional sort contexts to treat as safe")
	disable   = stringList("buildifier_disable", "list of buildifier rewrites to disable")

	// Experimental flags
	formatBzlFiles = flag.Bool("format_bzl", false, "format bzl-specific blocks (experimental)")
)

func stringList(name, help string) func() []string {
	f := flag.String(name, "", help)
	return func() []string {
		return strings.Split(*f, ",")
	}
}

func usage() {
	fmt.Fprintf(os.Stderr, `usage: buildifier [-d] [-v] [-mode=mode] [-path=path] [files...]

Buildifier applies a standard formatting to the named BUILD files.
The mode flag selects the processing: check, diff, fix, or print_if_changed.
In check mode, buildifier prints a list of files that need reformatting.
In diff mode, buildifier shows the diffs that it would make.
In fix mode, buildifier updates the files that need reformatting and,
if the -v flag is given, prints their names to standard error.
In print_if_changed mode, buildifier shows the file contents it would write.
The default mode is fix. -d is an alias for -mode=diff.

If no files are listed, buildifier reads a BUILD file from standard input. In
fix mode, it writes the reformatted BUILD file to standard output, even if no
changes are necessary.

Buildifier's reformatting depends in part on the path to the file relative
to the workspace directory. Normally buildifier deduces that path from the
file names given, but the path can be given explicitly with the -path
argument. This is especially useful when reformatting standard input,
or in scripts that reformat a temporary copy of a file.
`)
	os.Exit(2)
}

func main() {
	flag.Usage = usage
	flag.Parse()
	args := flag.Args()

	if *version {
		fmt.Printf("buildifier version: %s \n", buildifierVersion)
		fmt.Printf("buildifier scm revision: %s \n", buildScmRevision)

		if len(args) == 0 {
			os.Exit(0)
		}
	}

	// Pass down debug flags into build package
	build.DisableRewrites = disable()
	build.AllowSort = allowSort()

	tables.FormatBzlFiles = *formatBzlFiles

	if *dflag {
		if *mode != "" {
			fmt.Fprintf(os.Stderr, "buildifier: cannot specify both -d and -mode flags\n")
			os.Exit(2)
		}
		*mode = "diff"
	}

	// Check mode.
	switch *mode {
	default:
		fmt.Fprintf(os.Stderr, "buildifier: unrecognized mode %s; valid modes are check, diff, fix\n", *mode)
		os.Exit(2)

	case "":
		*mode = "fix"

	case "check", "diff", "fix", "print_if_changed":
		// ok
	}

	// If the path flag is set, must only be formatting a single file.
	// It doesn't make sense for multiple files to have the same path.
	if (*path != "" || *mode == "print_if_changed") && len(args) > 1 {
		fmt.Fprintf(os.Stderr, "buildifier: can only format one file when using -path flag or -mode=print_if_changed\n")
		os.Exit(2)
	}

	if *tablesPath != "" {
		if err := tables.ParseAndUpdateJSONDefinitions(*tablesPath, false); err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: failed to parse %s for -tables: %s\n", *tablesPath, err)
			os.Exit(2)
		}
	}

	if *addTablesPath != "" {
		if err := tables.ParseAndUpdateJSONDefinitions(*addTablesPath, true); err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: failed to parse %s for -add_tables: %s\n", *addTablesPath, err)
			os.Exit(2)
		}
	}

	diff = differ.Find()

	if len(args) == 0 || (len(args) == 1 && args[0] == "-") {
		// Read from stdin, write to stdout.
		data, err := ioutil.ReadAll(os.Stdin)<commit_msg>Change a flag for switching between build and bzl modes (#232)<commit_after>/*
Copyright 2016 Google Inc. All Rights Reserved.

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.
*/

// Buildifier, a tool to parse and format BUILD files.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"sort"
	"strings"

	"github.com/bazelbuild/buildtools/build"
	"github.com/bazelbuild/buildtools/differ"
	"github.com/bazelbuild/buildtools/tables"
)

var buildifierVersion = "redacted"
var buildScmRevision = "redacted"

var (
	// Undocumented; for debugging.
	showlog = flag.Bool("showlog", false, "show log in check mode")

	vflag         = flag.Bool("v", false, "print verbose information on standard error")
	dflag         = flag.Bool("d", false, "alias for -mode=diff")
	mode          = flag.String("mode", "", "formatting mode: check, diff, or fix (default fix)")
	path          = flag.String("path", "", "assume BUILD file has this path relative to the workspace directory")
	tablesPath    = flag.String("tables", "", "path to JSON file with custom table definitions which will replace the built-in tables")
	addTablesPath = flag.String("add_tables", "", "path to JSON file with custom table definitions which will be merged with the built-in tables")
	version       = flag.Bool("version", false, "Print the version of buildifier")

	// Debug flags passed through to rewrite.go
	allowSort = stringList("allowsort", "additional sort contexts to treat as safe")
	disable   = stringList("buildifier_disable", "list of buildifier rewrites to disable")

	// Experimental flags
	inputType = flag.String("type", "build", "Experimental: input file type: build (default, for BUILD files) or bzl (for .bzl files).")
)

func stringList(name, help string) func() []string {
	f := flag.String(name, "", help)
	return func() []string {
		return strings.Split(*f, ",")
	}
}

func usage() {
	fmt.Fprintf(os.Stderr, `usage: buildifier [-d] [-v] [-mode=mode] [-path=path] [files...]

Buildifier applies a standard formatting to the named BUILD files.
The mode flag selects the processing: check, diff, fix, or print_if_changed.
In check mode, buildifier prints a list of files that need reformatting.
In diff mode, buildifier shows the diffs that it would make.
In fix mode, buildifier updates the files that need reformatting and,
if the -v flag is given, prints their names to standard error.
In print_if_changed mode, buildifier shows the file contents it would write.
The default mode is fix. -d is an alias for -mode=diff.

If no files are listed, buildifier reads a BUILD file from standard input. In
fix mode, it writes the reformatted BUILD file to standard output, even if no
changes are necessary.

Buildifier's reformatting depends in part on the path to the file relative
to the workspace directory. Normally buildifier deduces that path from the
file names given, but the path can be given explicitly with the -path
argument. This is especially useful when reformatting standard input,
or in scripts that reformat a temporary copy of a file.
`)
	os.Exit(2)
}

func main() {
	flag.Usage = usage
	flag.Parse()
	args := flag.Args()

	if *version {
		fmt.Printf("buildifier version: %s \n", buildifierVersion)
		fmt.Printf("buildifier scm revision: %s \n", buildScmRevision)

		if len(args) == 0 {
			os.Exit(0)
		}
	}

	// Pass down debug flags into build package
	build.DisableRewrites = disable()
	build.AllowSort = allowSort()

	// Check input type.
	switch *inputType {
	case "bzl":
		tables.FormatBzlFiles = true

	case "build", "":
		tables.FormatBzlFiles = false

	default:
		fmt.Fprintf(os.Stderr, "buildifier: unrecognized input type %s; valid types are build, bzl\n", *inputType)
		os.Exit(2)
	}

	if *dflag {
		if *mode != "" {
			fmt.Fprintf(os.Stderr, "buildifier: cannot specify both -d and -mode flags\n")
			os.Exit(2)
		}
		*mode = "diff"
	}

	// Check mode.
	switch *mode {
	case "":
		*mode = "fix"

	case "check", "diff", "fix", "print_if_changed":
		// ok

	default:
		fmt.Fprintf(os.Stderr, "buildifier: unrecognized mode %s; valid modes are check, diff, fix\n", *mode)
		os.Exit(2)
	}

	// If the path flag is set, must only be formatting a single file.
	// It doesn't make sense for multiple files to have the same path.
	if (*path != "" || *mode == "print_if_changed") && len(args) > 1 {
		fmt.Fprintf(os.Stderr, "buildifier: can only format one file when using -path flag or -mode=print_if_changed\n")
		os.Exit(2)
	}

	if *tablesPath != "" {
		if err := tables.ParseAndUpdateJSONDefinitions(*tablesPath, false); err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: failed to parse %s for -tables: %s\n", *tablesPath, err)
			os.Exit(2)
		}
	}

	if *addTablesPath != "" {
		if err := tables.ParseAndUpdateJSONDefinitions(*addTablesPath, true); err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: failed to parse %s for -add_tables: %s\n", *addTablesPath, err)
			os.Exit(2)
		}
	}

	diff = differ.Find()

	if len(args) == 0 || (len(args) == 1 && args[0] == "-") {
		// Read from stdin, write to stdout.
		data, err := ioutil.ReadAll(os.Stdin)
{'fraction_non_alphanumeric': 0.11611528125289593, 'fraction_numerical': 0.004077471967380225, 'mean_word_length': 3.9211126310989513, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2848965', 'n_tokens_mistral': 3527, 'n_tokens_neox': 3337, 'n_words': 1290}