|
1 | 1 | /* |
2 | 2 | * Copyright 2011-2012 the original author or authors. |
3 | | - * |
| 3 | + * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
6 | 6 | * You may obtain a copy of the License at |
7 | | - * |
| 7 | + * |
8 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | - * |
| 9 | + * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software |
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
16 | 16 | package com.avast.server.hdfsshell.ui; |
17 | 17 |
|
18 | 18 | import com.avast.server.hdfsshell.commands.ContextCommands; |
| 19 | +import org.apache.commons.lang3.StringUtils; |
| 20 | +import org.slf4j.Logger; |
| 21 | +import org.slf4j.LoggerFactory; |
19 | 22 | import org.springframework.beans.factory.annotation.Autowired; |
20 | | -import org.springframework.boot.ansi.AnsiColor; |
21 | | -import org.springframework.boot.ansi.AnsiOutput; |
22 | 23 | import org.springframework.core.Ordered; |
23 | 24 | import org.springframework.core.annotation.Order; |
24 | 25 | import org.springframework.shell.core.AbstractShell; |
25 | 26 | import org.springframework.shell.plugin.support.DefaultPromptProvider; |
26 | 27 | import org.springframework.stereotype.Component; |
27 | 28 |
|
| 29 | +import javax.annotation.PostConstruct; |
| 30 | +import java.io.IOException; |
| 31 | +import java.util.Arrays; |
| 32 | +import java.util.Locale; |
| 33 | +import java.util.Set; |
| 34 | +import java.util.stream.Collectors; |
| 35 | + |
28 | 36 | /** |
29 | | - * @author Jarred Li |
| 37 | + * @author Vitasek L. |
30 | 38 | */ |
31 | 39 | @Component |
32 | 40 | @Order(Ordered.HIGHEST_PRECEDENCE) |
33 | 41 | public class ShellPromptProvider extends DefaultPromptProvider { |
34 | 42 |
|
| 43 | + private static final Logger logger = LoggerFactory.getLogger(ShellPromptProvider.class); |
| 44 | + |
| 45 | + private static final String DEFAULT_PROMPT = "\033[36m\\u@\\h \033[0;39m\033[33m\\w\033[0;39m\033[36m\\$ \033[37;0;39m"; |
35 | 46 | final ContextCommands contextCommands; |
36 | 47 |
|
| 48 | + private SimpleBashPromptInterpreter simpleBashPromptInterpreter; |
| 49 | + |
37 | 50 | @Autowired |
38 | 51 | public ShellPromptProvider(ContextCommands contextCommands) { |
39 | 52 | this.contextCommands = contextCommands; |
40 | 53 | } |
41 | 54 |
|
| 55 | + @PostConstruct |
| 56 | + public void init() { |
| 57 | + setPs1(System.getenv().getOrDefault("HDFS_SHELL_PROMPT", DEFAULT_PROMPT)); |
| 58 | + } |
| 59 | + |
| 60 | + public void setPs1(String ps1) { |
| 61 | + simpleBashPromptInterpreter = new SimpleBashPromptInterpreter.Builder(ps1). |
| 62 | + setAppName(() -> "hdfs-shell").setAppVersion(ShellBannerProvider::versionInfo). |
| 63 | + setLocale(Locale.ENGLISH). |
| 64 | + setUsername(this::getWhoami). |
| 65 | + setIsRoot(this::isRootPrompt). |
| 66 | + setCwdAbsolut(contextCommands::getCurrentDir). |
| 67 | + setCwdShort(this::getShortCwd). |
| 68 | + build(); |
| 69 | + } |
| 70 | + |
| 71 | + private boolean isRootPrompt() { |
| 72 | + final String whoami = this.getWhoami(); |
| 73 | + final String[] groupsForUser = contextCommands.getGroupsForUser(whoami); |
| 74 | + if (groupsForUser.length == 0) { //make guess |
| 75 | + return "root".equals(whoami) || "hdfs".equals(whoami); |
| 76 | + } |
| 77 | + final String[] groups = contextCommands.getConfiguration().get("dfs.permissions.superusergroup", "supergroup").split(","); |
| 78 | + final Set<String> adminGroups = Arrays.stream(groups).map(String::trim).collect(Collectors.toSet()); |
| 79 | + adminGroups.add("Administrators");//for Windows |
| 80 | + adminGroups.add("hdfs");//special cases |
| 81 | + adminGroups.add("root"); |
| 82 | + return Arrays.stream(groupsForUser).anyMatch(adminGroups::contains); |
| 83 | + } |
42 | 84 |
|
43 | 85 | @Override |
44 | 86 | public String getPrompt() { |
45 | | - return AbstractShell.shellPrompt = |
46 | | - AnsiOutput.toString(AnsiColor.CYAN, "hdfs-shell ") + |
47 | | - AnsiOutput.toString(AnsiColor.YELLOW, contextCommands.getCurrentDir()) + |
48 | | - AnsiOutput.toString(AnsiColor.CYAN, " >", AnsiColor.WHITE); |
| 87 | + return AbstractShell.shellPrompt = simpleBashPromptInterpreter.interpret(); |
| 88 | + } |
| 89 | + |
| 90 | + private String getWhoami() { |
| 91 | + try { |
| 92 | + return contextCommands.whoami(); |
| 93 | + } catch (IOException e) { |
| 94 | + logger.error("Failed to get active user", e); |
| 95 | + return "hdfs-shell"; |
| 96 | + } |
49 | 97 | } |
50 | 98 |
|
| 99 | +// private String defaultPrompt() { |
| 100 | +// return AnsiOutput.toString(AnsiColor.CYAN, "hdfs-shell ") + |
| 101 | +// AnsiOutput.toString(AnsiColor.YELLOW, contextCommands.getCurrentDir()) + |
| 102 | +// AnsiOutput.toString(AnsiColor.CYAN, " >", AnsiColor.WHITE); |
| 103 | +// } |
| 104 | + |
51 | 105 |
|
52 | 106 | @Override |
53 | 107 | public String getProviderName() { |
54 | 108 | return "Hdfs-shell prompt"; |
55 | 109 | } |
56 | 110 |
|
| 111 | + private String getShortCwd() { |
| 112 | + String currentDir = contextCommands.getCurrentDir(); |
| 113 | + if (currentDir.startsWith("/user/")) { |
| 114 | + final String userHome = "/user/" + this.getWhoami();//call getWhoami later |
| 115 | + if (currentDir.startsWith(userHome)) { |
| 116 | + currentDir = StringUtils.replaceOnce(currentDir, userHome, "~"); |
| 117 | + } |
| 118 | + } |
| 119 | + return currentDir; |
| 120 | + } |
57 | 121 | } |
0 commit comments