This file is indexed.

/usr/lib/ruby/vendor_ruby/sass/exec/sass_convert.rb is in ruby-sass 3.4.6-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
require 'optparse'
require 'fileutils'

module Sass::Exec
  # The `sass-convert` executable.
  class SassConvert < Base
    # @param args [Array<String>] The command-line arguments
    def initialize(args)
      super
      require 'sass'
      @options[:for_tree] = {}
      @options[:for_engine] = {:cache => false, :read_cache => true}
    end

    # Tells optparse how to parse the arguments.
    #
    # @param opts [OptionParser]
    def set_opts(opts)
      opts.banner = <<END
Usage: sass-convert [options] [INPUT] [OUTPUT]

Description:
  Converts between CSS, indented syntax, and SCSS files. For example,
  this can convert from the indented syntax to SCSS, or from CSS to
  SCSS (adding appropriate nesting).
END

      common_options(opts)
      style(opts)
      input_and_output(opts)
      miscellaneous(opts)
    end

    # Processes the options set by the command-line arguments,
    # and runs the CSS compiler appropriately.
    def process_result
      require 'sass'

      if @options[:recursive]
        process_directory
        return
      end

      super
      input = @options[:input]
      if File.directory?(input)
        raise "Error: '#{input.path}' is a directory (did you mean to use --recursive?)"
      end
      output = @options[:output]
      output = input if @options[:in_place]
      process_file(input, output)
    end

    private

    def common_options(opts)
      opts.separator ''
      opts.separator 'Common Options:'

      opts.on('-F', '--from FORMAT',
        'The format to convert from. Can be css, scss, sass.',
        'By default, this is inferred from the input filename.',
        'If there is none, defaults to css.') do |name|
        @options[:from] = name.downcase.to_sym
        raise "sass-convert no longer supports LessCSS." if @options[:from] == :less
        unless [:css, :scss, :sass].include?(@options[:from])
          raise "Unknown format for sass-convert --from: #{name}"
        end
      end

      opts.on('-T', '--to FORMAT',
        'The format to convert to. Can be scss or sass.',
        'By default, this is inferred from the output filename.',
        'If there is none, defaults to sass.') do |name|
        @options[:to] = name.downcase.to_sym
        unless [:scss, :sass].include?(@options[:to])
          raise "Unknown format for sass-convert --to: #{name}"
        end
      end

      opts.on('-i', '--in-place',
        'Convert a file to its own syntax.',
        'This can be used to update some deprecated syntax.') do
        @options[:in_place] = true
      end

      opts.on('-R', '--recursive',
          'Convert all the files in a directory. Requires --from and --to.') do
        @options[:recursive] = true
      end

      opts.on("-?", "-h", "--help", "Show this help message.") do
        puts opts
        exit
      end

      opts.on("-v", "--version", "Print the Sass version.") do
        puts("Sass #{Sass.version[:string]}")
        exit
      end
    end

    def style(opts)
      opts.separator ''
      opts.separator 'Style:'

      opts.on('--dasherize', 'Convert underscores to dashes.') do
        @options[:for_tree][:dasherize] = true
      end

      opts.on('--indent NUM',
        'How many spaces to use for each level of indentation. Defaults to 2.',
        '"t" means use hard tabs.') do |indent|

        if indent == 't'
          @options[:for_tree][:indent] = "\t"
        else
          @options[:for_tree][:indent] = " " * indent.to_i
        end
      end

      opts.on('--old', 'Output the old-style ":prop val" property syntax.',
                       'Only meaningful when generating Sass.') do
        @options[:for_tree][:old] = true
      end
    end

    def input_and_output(opts)
      opts.separator ''
      opts.separator 'Input and Output:'

      opts.on('-s', '--stdin', :NONE,
              'Read input from standard input instead of an input file.',
              'This is the default if no input file is specified. Requires --from.') do
        @options[:input] = $stdin
      end

      encoding_option(opts)

      opts.on('--unix-newlines', 'Use Unix-style newlines in written files.',
                                 ('Always true on Unix.' unless Sass::Util.windows?)) do
        @options[:unix_newlines] = true if Sass::Util.windows?
      end
    end

    def miscellaneous(opts)
      opts.separator ''
      opts.separator 'Miscellaneous:'

        opts.on('--cache-location PATH',
                'The path to save parsed Sass files. Defaults to .sass-cache.') do |loc|
          @options[:for_engine][:cache_location] = loc
        end

      opts.on('-C', '--no-cache', "Don't cache to sassc files.") do
        @options[:for_engine][:read_cache] = false
      end

      opts.on('--trace', :NONE, 'Show a full Ruby stack trace on error') do
        @options[:trace] = true
      end
    end

    def process_directory
      unless @options[:input] = @args.shift
        raise "Error: directory required when using --recursive."
      end

      output = @options[:output] = @args.shift
      raise "Error: --from required when using --recursive." unless @options[:from]
      raise "Error: --to required when using --recursive." unless @options[:to]
      unless File.directory?(@options[:input])
        raise "Error: '#{@options[:input]}' is not a directory"
      end
      if @options[:output] && File.exist?(@options[:output]) &&
        !File.directory?(@options[:output])
        raise "Error: '#{@options[:output]}' is not a directory"
      end
      @options[:output] ||= @options[:input]

      if @options[:to] == @options[:from] && !@options[:in_place]
        fmt = @options[:from]
        raise "Error: converting from #{fmt} to #{fmt} without --in-place"
      end

      ext = @options[:from]
      Sass::Util.glob("#{@options[:input]}/**/*.#{ext}") do |f|
        output =
          if @options[:in_place]
            f
          elsif @options[:output]
            output_name = f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}")
            output_name[0...@options[:input].size] = @options[:output]
            output_name
          else
            f.gsub(/\.(c|sa|sc|le)ss$/, ".#{@options[:to]}")
          end

        unless File.directory?(File.dirname(output))
          puts_action :directory, :green, File.dirname(output)
          FileUtils.mkdir_p(File.dirname(output))
        end
        puts_action :convert, :green, f
        if File.exist?(output)
          puts_action :overwrite, :yellow, output
        else
          puts_action :create, :green, output
        end

        process_file(f, output)
      end
    end

    def process_file(input, output)
      input_path, output_path = path_for(input), path_for(output)
      if input_path
        @options[:from] ||=
          case input_path
          when /\.scss$/; :scss
          when /\.sass$/; :sass
          when /\.less$/; raise "sass-convert no longer supports LessCSS."
          when /\.css$/; :css
          end
      elsif @options[:in_place]
        raise "Error: the --in-place option requires a filename."
      end

      if output_path
        @options[:to] ||=
          case output_path
          when /\.scss$/; :scss
          when /\.sass$/; :sass
          end
      end

      @options[:from] ||= :css
      @options[:to] ||= :sass
      @options[:for_engine][:syntax] = @options[:from]

      out =
        Sass::Util.silence_sass_warnings do
          if @options[:from] == :css
            require 'sass/css'
            Sass::CSS.new(input.read, @options[:for_tree]).render(@options[:to])
          else
            if input_path
              Sass::Engine.for_file(input_path, @options[:for_engine])
            else
              Sass::Engine.new(input.read, @options[:for_engine])
            end.to_tree.send("to_#{@options[:to]}", @options[:for_tree])
          end
        end

      output = input_path if @options[:in_place]
      write_output(out, output)
    rescue Sass::SyntaxError => e
      raise e if @options[:trace]
      file = " of #{e.sass_filename}" if e.sass_filename
      raise "Error on line #{e.sass_line}#{file}: #{e.message}\n  Use --trace for backtrace"
    rescue LoadError => err
      handle_load_error(err)
    end

    def path_for(file)
      return file.path if file.is_a?(File)
      return file if file.is_a?(String)
    end
  end
end